我将 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中实现吗?
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();
}