Qt QModel 视图使用 QSortFilterProxyModel 功能太慢,出问题了吗?

问题描述 投票:0回答:1

我将 Qt 模型视图与 QSortFilterProxyModel 一起使用

带有复选框和名称的QListView,只有一列

QStandardItemModel setData ,100w 行

使用QSortFilterProxyModel函数setFilterFixedString

并添加一个功能更改所有行复选框已选中

在我的类继承QStandardItemModel中就像这样

void toggleAllItemsInModel(QStandardItemModel* model, bool checked)
{
    for (int i = 0; i < model->rowCount(); ++i) {
        QStandardItem* item = model->item(i);
        if (item && item->isCheckable()) {
            item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
        }
}

我的问题是toggleAllItemsInModel这个函数只用了0.1s,但是setFilterFixedString用了12s以上,为什么这个函数这么慢而且我认为Qt模型视图已经优化了视图显示,我需要优化,请给一些建议。

我使用modelItem userole + 1保存隐藏标记,并添加函数filterAcccptsRow,但也使用12s, 设置DynamicSortFilter(false)和setFilterRole(Qt::DisplayRole),但没有用。

更好的功能不是使用QSortFilterProxyModel并在QStandardItemModel中实现吗?

c++ qt qt5
1个回答
0
投票
this is test code like my code,only two function selectAll and filterString,use Qt5.15,CentOS Linux 7,release version test

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QListView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QLineEdit>
#include <QPushButton>
#include <QCheckBox>

class CheckableStandardItemModel : public QStandardItemModel {
    Q_OBJECT
public:
    CheckableStandardItemModel(QObject *parent = nullptr) : QStandardItemModel(parent) {
    setColumnCount(1);
}


    // select all checkbox 
    void selectAll(bool select) {

        for (int row = 0; row < rowCount(); ++row) {
            QStandardItem *item = item(row, 0);
            if (item) {
                item->setCheckState(select ? Qt::Checked : Qt::Unchecked);
            }
        }
    }
};

class TestWindow : public QWidget {
    Q_OBJECT
public:
    TestWindow(QWidget *parent = nullptr) : QWidget(parent) {
        setupUi();
        setupModel();
        setupProxyModel();
        connectSignals();
    }

private:
    QListView *listView;
    CheckableStandardItemModel *model;
    QSortFilterProxyModel *proxyModel;
    QLineEdit *filterLineEdit;
    QPushButton *filterButton;
    QCheckBox *selectAllCheckbox;

    void setupUi() {
        QVBoxLayout *layout = new QVBoxLayout(this);
        listView = new QListView(this);
        filterLineEdit = new QLineEdit(this);
        filterButton = new QPushButton("Filter", this);
        selectAllCheckbox = new QCheckBox("Select All", this);
        layout->addWidget(listView);
        layout->addWidget(filterLineEdit);
        layout->addWidget(filterButton);
        layout->addWidget(selectAllCheckbox);
    }

    void setupModel() {
        model = new CheckableStandardItemModel(this);
        model->setHorizontalHeaderLabels(QStringList("Name"));
        for(int i = 0; i < 1000000; ++i) {
            QStandardItem *item = new QStandardItem(QString("Item%1").arg(i));
            item->setCheckable(true);

            model->appendRow(item);
        }
    }

    void setupProxyModel() {
        proxyModel = new QSortFilterProxyModel(this);
        proxyModel->setSourceModel(model);
        proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
        listView->setModel(proxyModel);
    }

    void connectSignals() {
        connect(filterLineEdit, &QLineEdit::textChanged, this, [this](const QString& text) {
            //test time here
            proxyModel->setFilterFixedString(text);
        });
        connect(selectAllCheckbox, &QCheckBox::stateChanged, this, [this](int state) {
            //test time here
            model->selectAll(state == Qt::Checked);
        });
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    TestWindow window;
    window.show();
    return app.exec();
}
© www.soinside.com 2019 - 2024. All rights reserved.