如何在QTableView中显示QAbstractItemModel的子行

时间:2016-06-02 09:52:19

标签: c++ qt model-view-controller qtreeview model-view

我有自己的类,它继承自QAbstractItemModel,它具有树结构。

我使用几个视图,使用从QSortFilterProxyModel派生的类显示此模型的过滤数据。

我的模型结构如下所示:

root
|
-- A
|  |-A1
|  |-A2
|  |-A3
|
-- B
|  |-B1
|  |-B2
|
... and so on...

其中A,B ....是"主要行" (根的孩子),A1,A2,...... B1,B2 ......是"子行" - 节点行追加到"主行"。

现在,我需要做的是显示"子行"的QTableView。只有:

A1
A2
A3
B1
B2

但我在QSortFilterProxyModel(filterAcceptsRow,filterAcceptsColumn)中找到的过滤方法仅在主行上运行...

我该怎么做?

(我发现了非常相似的问题,但仍然没有答案:QTableView to display only leaves of a tree model implemented with QAbstractItemModel

1 个答案:

答案 0 :(得分:2)

我看到了3个可能的解决方案。前两个解决方案在他对此问题的评论中提供了Dmitry Sazonov

  1. 重新实现QAbstractProxyModel
  2. 重新实现QAbstractItemModel并为此类视图创建另一个模型。
  3. 第三种可能的解决方案是重新实现QStyledItemDelegate视图的小技巧。我为这种解决方案做了一个小例子。我希望,这将是有用的:

    #include <QApplication>
    #include <QTreeView>
    #include <QStyledItemDelegate>
    #include <QStandardItemModel>
    
    class ZeroHightItemDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        ZeroHightItemDelegate(QObject* parent = 0)
            : QStyledItemDelegate(parent)
        {}
        ~ZeroHightItemDelegate(){}
    public:
        QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE
        {
            static int defaultHeight = 0;
            static bool firstSizeHintFlag = true;
            QSize size = QStyledItemDelegate::sizeHint(option, index);
            if (firstSizeHintFlag){
                defaultHeight = size.height();
                firstSizeHintFlag = false;
            }
            const QAbstractItemModel* model = index.model();
            if (!model)
                return size;
            if (model->hasChildren(index))
                size.setHeight(0);
            else
                size.setHeight(defaultHeight);
            return size;
        }
    };
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QTreeView myView;
        myView.setRootIsDecorated(false);
        QStandardItemModel* model = new QStandardItemModel(&myView);
        myView.setModel(model);
    
        model->insertColumns(0, 1);
        QStandardItem* headerItem = new QStandardItem("Header");
        model->setHorizontalHeaderItem(0, headerItem);
    
        QStandardItem* itemA = new QStandardItem("A");
        model->appendRow(itemA);
        QStandardItem* itemB = new QStandardItem("B");
        model->appendRow(itemB);
        QStandardItem* itemA1 = new QStandardItem("A1");
        QStandardItem* itemA2 = new QStandardItem("A2");
        itemA->appendRow(itemA1);
        itemA->appendRow(itemA2);
        QStandardItem* itemB1 = new QStandardItem("B1");
        QStandardItem* itemB2 = new QStandardItem("B2");
        QStandardItem* itemB3 = new QStandardItem("B3");
        itemB->appendRow(itemB1);
        itemB->appendRow(itemB2);
        itemB->appendRow(itemB3);
        myView.setItemDelegate(new ZeroHightItemDelegate(&myView));
    
        myView.expandAll();
        myView.show();
    
        return a.exec();
    }
    
    #include "main.moc"