1

I use Qt Model view with QSortFilterProxyModel

QListView with checkbox and name ,only one column

QStandardItemModel setData ,100w row

use QSortFilterProxyModel function setFilterFixedString

and add a function changed all row checkbox checked

like this in my class Inheritance 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);
        }
}

my question is this function toggleAllItemsInModel only use 0.1s ,but setFilterFixedString use more than 12s,why this function is so slow and i think Qt model view has been optimized view show, i need optimize,please give some advice.

i use modelItem userole + 1 save hidden mark ,and add function filterAccptsRow,but alse use 12s, set DynamicSortFilter(false), and setFilterRole(Qt::DisplayRole),but no use.

a better function is not use QSortFilterProxyModel and realizing in QStandardItemModel?

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) {
            beginResetModel();
            for (int row = 0; row < rowCount(); ++row) {
                QStandardItem *item = item(row, 0);
                if (item) {
                    item->setCheckState(select ? Qt::Checked : Qt::Unchecked);
                }
            }
            endResetModel();
        }
    };
    
    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);
                listView->viewport()->update();
            });
        }
    };
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        TestWindow window;
        window.show();
        return app.exec();
    }
10
  • 1
    Please show a minimal reproducible example. Are you running in debug or release? Commented Jul 1 at 3:45
  • @ Alan Birtles add test code. Commented Jul 1 at 7:00
  • 3
    are you using debug or release? Commented Jul 1 at 11:30
  • Setting the checkstate or changing a filter is not the same thing (especially considering the amount of items you have). Also, please use functions appropriately: beginResetModel() and endResetModel() are to be used when the model is actually reset or as an alternative to dataChanged(): since you're using QStandardItemModel, that makes it completely useless, since it will emit dataChanged anyway when doing setCheckState(), unless you block its signals. It should also be unnecessary to update the viewport (if things are done appropriately). Commented Jul 1 at 11:36
  • thanks,my real code and beginResetModel,and endResetModel function, and i add blocksignal function. And i think save checked state and filter item to hidden can be save with Commented Jul 2 at 6:11

0

Browse other questions tagged or ask your own question.