Hide future columns of QStandardItemModel in QTreeView

烈酒焚心 提交于 2020-01-06 01:29:06

问题


I have a QStandardItemModel. This model might get additional columns via an input widget.

In addition, the QStandardItemModel is the model of a QTreeView.

I would like to guarantee that just the first n columns of the QStandardItemModel are visualised in the QTreeView.

How could I achieve this?

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.

What is my motivation?

I would like to visualise the first n columns in a QTreeView. On selection of an item the remaining columns (of the row of the selected item) shall be presented in a QTableWidget as rows.


回答1:


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.

You are correct that the model is unaware of the view. This is exactly how it should be and is good practice. The Qt Model-View Framework is a good practical implementation of the Model-View-Controller (MVC) Pattern

Models are not supposed to know what's going to be viewed or not, thier responsibility is to store and organise data and properties of those data.

Views connect to models and have a read-only relationship with them. They must be notified when changes are made to the models so that they know that they must update themselves. In Qt this is done by connecting signals in the model to slots in the view. These connections are made in the function QAbstractItemView::setModel

Your question deals specifically with the display of columns and in Qt, the main Item View classes delegate the responsibility of column and row visibility to the QHeaderView class, which is created automatically by all views by default.

If you want to create special functionality, you need to either manipulate these default views, or else setting a custom header view to the main view.

I've done the second option.

I've also connected the model to two views, one that is limited to show only the first 5 columns and the second one without a custom header view. This is to show that the underlying model is completely unaware of the viewing restrictions and still contains the complete data set.

#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();
}


来源:https://stackoverflow.com/questions/33053125/hide-future-columns-of-qstandarditemmodel-in-qtreeview

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!