Скрыть будущие столбцы QStandardItemModel в QTreeView
У меня есть QStandardItemModel
, Эта модель может получить дополнительные столбцы через виджет ввода.
В дополнение QStandardItemModel
это модель QTreeView
,
Я хотел бы гарантировать, что только первые n столбцов QStandardItemModel
визуализируются в QTreeView
,
Как я мог этого добиться?
Но:
- Модель не знает о представлении (предположим, что Qt что-то делает в фоновом режиме)
- Представление не информируется об обновленных столбцах моим кодом. Тем не менее, новые столбцы визуализируются.
Какова моя мотивация?
Я хотел бы визуализировать первые n столбцов в QTreeView
, При выборе элемента остальные столбцы (строки выбранного элемента) должны быть представлены в QTableWidget
как строки.
1 ответ
Но:
- Модель не знает о представлении (предположим, что Qt что-то делает в фоновом режиме)
- Представление не информируется об обновленных столбцах моим кодом. Тем не менее, новые столбцы визуализируются.
Вы правы, что модель не знает о представлении. Именно так и должно быть, и это хорошая практика. Каркас Qt Model-View является хорошей практической реализацией шаблона Model-View-Controller (MVC).
Модели не должны знать, что будет просматриваться или нет, их обязанность - хранить и систематизировать данные и свойства этих данных.
Представления подключаются к моделям и имеют с ними отношения только для чтения. Они должны быть уведомлены о внесении изменений в модели, чтобы они знали, что они должны обновить себя. В Qt
это делается путем подключения сигналов в модели к слотам на виде. Эти соединения сделаны в функции QAbstractItemView::setModel
Ваш вопрос касается конкретно отображения столбцов и в Qt
основные классы Item View делегируют ответственность за видимость столбцов и строк QHeaderView
класс, который создается автоматически всеми представлениями по умолчанию.
Если вы хотите создать специальную функциональность, вам нужно либо манипулировать этими представлениями по умолчанию, либо установить настраиваемый вид заголовка для основного вида.
Я сделал второй вариант.
Я также подключил модель к двум представлениям, одно из которых ограничено отображением только первых 5 столбцов, а второе - без настраиваемого представления заголовка. Это должно показать, что базовая модель полностью не знает об ограничениях просмотра и все еще содержит полный набор данных.
#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();
}