在 QTreeView 中隐藏 QStandardItemModel 的未来列
Hide future columns of QStandardItemModel in QTreeView
我有一个QStandardItemModel
。此模型可能会通过输入小部件获得额外的列。
另外,QStandardItemModel
是一个QTreeView
的模型。
我想保证只有 QStandardItemModel
的前 n 列在 QTreeView
中可视化。
我怎样才能做到这一点?
但是:
- 模型不知道视图(期望 Qt 在后台做一些事情)
- 视图未通过我的代码通知更新的列。尽管如此,新列还是可视化的。
我的动力是什么?
我想可视化 QTreeView
中的前 n 列。在选择一个项目时,剩余的列(所选项目的行)应在 QTableWidget
中显示为行。
But:
- The model is not aware of the view (expect Qt does something in the background)
- The view is not informed about the updated columns by my code. Nevertheless, the new columns are visualised.
你说得对,模型不知道视图。这正是它应该的样子,也是一种很好的做法。 Qt Model-View 框架是 Model-View-Controller (MVC) Pattern
的一个很好的实用实现
模型不应该知道将要查看或不查看什么,他们的责任是存储和组织数据以及这些数据的属性。
视图连接到模型并与模型建立 read-only 关系。当对模型进行更改时,必须通知他们,以便他们知道必须更新自己。在 Qt
中,这是通过将模型中的信号连接到视图中的槽来完成的。这些连接是在函数 QAbstractItemView::setModel
中建立的
您的问题专门针对列的显示,在 Qt
中,主项目视图 classes 将列和行可见性的责任委托给 QHeaderView
class, 默认情况下由所有视图自动创建。
如果您想创建特殊功能,您需要操作这些默认视图,或者将自定义 header 视图设置为主视图。
我选择了第二个选项。
我还将模型连接到两个视图,一个仅限于显示前 5 列,第二个没有自定义 header 视图。这是为了表明底层模型完全不知道查看限制,仍然包含完整的数据集。
#include <QtWidgets/QApplication>
#include <QtWidgets/qtreeview.h>
#include <QtGui/qstandarditemmodel.h>
#include <QtWidgets/QHeaderView>
class RestrictedHeaderView : public QHeaderView {
Q_OBJECT
public:
RestrictedHeaderView(int cols, QWidget *parent = 0) : QHeaderView(Qt::Horizontal, parent), visibleColumns(cols) {}
protected slots:
virtual void sectionsInserted(QModelIndex const &parent, int logicalFirst, int logicalLast){
if (!parent.isValid() && logicalLast >= visibleColumns){
for (int col = visibleColumns; col <= logicalLast; ++col){
hideSection(col);
}
}
}
private:
int visibleColumns;
};
#include "main.moc"
int main(int argc, char** argv){
QApplication app(argc, argv);
QTreeView view;
view.setWindowTitle("Limited View");
QTreeView view2;
view2.setWindowTitle("Complete View");
QStandardItemModel model(4, 4);
for(int row = 0; row < 4; ++row){
for(int column = 0; column < 4; ++column){
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model.setItem(row, column, item);
}
}
// Apply the model to both views and show them
view.setModel(&model);
view.show();
view2.setModel(&model);
view2.show();
// set a custom header to the limited view only so that it automatically hides all columns that are inserted after the fifth column
view.setHeader(new RestrictedHeaderView(5));
// Add new columns to the underlying model
model.insertColumns(4, 3);
for (int row = 0; row < 4; ++row){
for(int column = 4; column < 7; ++column){
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model.setItem(row, column, item);
}
}
return app.exec();
}
我有一个QStandardItemModel
。此模型可能会通过输入小部件获得额外的列。
另外,QStandardItemModel
是一个QTreeView
的模型。
我想保证只有 QStandardItemModel
的前 n 列在 QTreeView
中可视化。
我怎样才能做到这一点?
但是:
- 模型不知道视图(期望 Qt 在后台做一些事情)
- 视图未通过我的代码通知更新的列。尽管如此,新列还是可视化的。
我的动力是什么?
我想可视化 QTreeView
中的前 n 列。在选择一个项目时,剩余的列(所选项目的行)应在 QTableWidget
中显示为行。
But:
- The model is not aware of the view (expect Qt does something in the background)
- The view is not informed about the updated columns by my code. Nevertheless, the new columns are visualised.
你说得对,模型不知道视图。这正是它应该的样子,也是一种很好的做法。 Qt Model-View 框架是 Model-View-Controller (MVC) Pattern
的一个很好的实用实现模型不应该知道将要查看或不查看什么,他们的责任是存储和组织数据以及这些数据的属性。
视图连接到模型并与模型建立 read-only 关系。当对模型进行更改时,必须通知他们,以便他们知道必须更新自己。在 Qt
中,这是通过将模型中的信号连接到视图中的槽来完成的。这些连接是在函数 QAbstractItemView::setModel
您的问题专门针对列的显示,在 Qt
中,主项目视图 classes 将列和行可见性的责任委托给 QHeaderView
class, 默认情况下由所有视图自动创建。
如果您想创建特殊功能,您需要操作这些默认视图,或者将自定义 header 视图设置为主视图。
我选择了第二个选项。
我还将模型连接到两个视图,一个仅限于显示前 5 列,第二个没有自定义 header 视图。这是为了表明底层模型完全不知道查看限制,仍然包含完整的数据集。
#include <QtWidgets/QApplication>
#include <QtWidgets/qtreeview.h>
#include <QtGui/qstandarditemmodel.h>
#include <QtWidgets/QHeaderView>
class RestrictedHeaderView : public QHeaderView {
Q_OBJECT
public:
RestrictedHeaderView(int cols, QWidget *parent = 0) : QHeaderView(Qt::Horizontal, parent), visibleColumns(cols) {}
protected slots:
virtual void sectionsInserted(QModelIndex const &parent, int logicalFirst, int logicalLast){
if (!parent.isValid() && logicalLast >= visibleColumns){
for (int col = visibleColumns; col <= logicalLast; ++col){
hideSection(col);
}
}
}
private:
int visibleColumns;
};
#include "main.moc"
int main(int argc, char** argv){
QApplication app(argc, argv);
QTreeView view;
view.setWindowTitle("Limited View");
QTreeView view2;
view2.setWindowTitle("Complete View");
QStandardItemModel model(4, 4);
for(int row = 0; row < 4; ++row){
for(int column = 0; column < 4; ++column){
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model.setItem(row, column, item);
}
}
// Apply the model to both views and show them
view.setModel(&model);
view.show();
view2.setModel(&model);
view2.show();
// set a custom header to the limited view only so that it automatically hides all columns that are inserted after the fifth column
view.setHeader(new RestrictedHeaderView(5));
// Add new columns to the underlying model
model.insertColumns(4, 3);
for (int row = 0; row < 4; ++row){
for(int column = 4; column < 7; ++column){
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model.setItem(row, column, item);
}
}
return app.exec();
}