在QTreeView中隐藏QStandardItemModel的未来列 [英] Hide future columns of QStandardItemModel in QTreeView

查看:2300
本文介绍了在QTreeView中隐藏QStandardItemModel的未来列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 QStandardItemModel 。此模型可能通过输入小部件获取其他列。



此外, QStandardItemModel code> QTreeView 。



我想保证只有 QStandardItemModel QTreeView 中可视化。



如何实现?



但是:




  • 模型不知道视图(期望Qt在后台执行某些操作)

  • 视图不会通过我的代码通知更新的列。



我的动机是什么?



我想要在 QTreeView 中显示前n列。在选择项目时,剩余的列(所选项目的行)将以 QTableWidget 作为行来呈现。

解决方案


但是:




  • (期望Qt在后台执行某些操作)

  • 视图不会通过我的代码通知更新的列。

您确定模型不知道视图。这正是它应该是什么,是良好的做法。 Qt模型视图框架是的一个很好的实际实现模型 - 视图 - 控制器(MVC)模式



模型不应该知道要查看什么或不会,所以负责存储和组织数据和这些数据的属性。



视图连接到模型,并与它们具有只读关系。当对模型进行更改时,必须通知他们,以便他们知道他们必须更新自己。在 Qt 中,这是通过将模型中的信号连接到视图中的插槽来实现的。这些连接是在函数 QAbstractItemView :: setModel



中创建的。您的问题专门针对列的显示, Qt ,主要的Item View类将列和行可见性的责任委托给 QHeaderView 类,



如果您要创建特殊功能,您需要操作这些默认视图,或者在主视图中设置自定义标题视图。



我做了第二个选项。



我还将模型连接到两个视图,一个限制为只显示前5列,第二个没有自定义标题视图。这是为了显示底层模型完全不知道观看限制,仍然包含完整的数据集。

  #include< ; QtWidgets / QApplication> 
#include< QtWidgets / qtreeview.h>
#include #include< QtWidgets / QHeaderView>

类RestrictedHeaderView(int cols,QWidget * parent = 0):QHeaderView(Qt :: Horizo​​ntal,parent) ,visibleColumns(cols){}

protected slots:
virtual void sectionsInserted(QModelIndex const& parent,int logicalFirst,int logicalLast){
if(!parent.isValid )&&&&&&> = visibleColumns){
for(int col = visibleColumns; col< = logicalLast; ++ col){
hideSection
}
}
}

private:
int visibleColumns;
};

#includemain.moc

int main(int argc,char ** argv){
QApplication app(argc,argv)

QTreeView视图;
view.setWindowTitle(Limited View);
QTreeView view2;
view2.setWindowTitle(Complete View);

QStandardItemModel模型(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);
}
}

//将模型应用到这两个视图并显示它们
view.setModel(& model);
view.show();
view2setModel(& model);
view2.show();

//设置自定义头到限制视图,以便它自动隐藏所有插入第五列后的列
view.setHeader(new RestrictedHeaderView(5));

//向底层模型添加新列
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();
}


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.

解决方案

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

这篇关于在QTreeView中隐藏QStandardItemModel的未来列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆