【问题标题】:To set widgets on children items on QTreeView在 QTreeView 上的子项上设置小部件
【发布时间】:2013-02-23 09:19:21
【问题描述】:

感谢this thread,我能够将小部件添加到view 的顶级项目的QAbstractItemView(在我的示例中为QTreeView)的第二列或更高列。

但是是否可以向子项添加小部件?

以下是我尝试过的部分成功的方法:

#!/usr/bin/env python
import os

from PyQt4.QtCore import QModelIndex, Qt
from PyQt4.QtGui import QApplication, QItemSelectionModel, \
                        QPushButton, QStandardItem, \
                        QStandardItemModel, QTreeView
from PyQt4.uic import loadUi


class PrvTreeviewNest(QTreeView):
    def __init__(self):
        super(PrvTreeviewNest, self).__init__()

        loadUi('/home/user/yourproject/resource/treeview_nest.ui')

        # row can be 0 even when it's more than 0.
        self._datamodel = QStandardItemModel(0, 2)
        self.setModel(self._datamodel)

        for i in range(4):
            self._add_widget(i + 1)

        self.show()

    def _add_widget(self, n):
        std_item = QStandardItem('{}th item'.format(n))
        self._datamodel.setItem(n, 0, std_item)

        node_widget = QPushButton('{}th button'.format(n))
        qindex_widget = self._datamodel.index(n, 1, QModelIndex())
        self.setIndexWidget(qindex_widget, node_widget)

        if n == 2:
            std_item_child = QStandardItem('child')
            std_item.appendRow(std_item_child)

            node_widget_child = QPushButton('petit button')
            qindex_widget_child = self._datamodel.index(n, 1, QModelIndex())
            self.setIndexWidget(qindex_widget_child, node_widget_child)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    # window = TreeviewWidgetSelectProve()
    window = PrvTreeviewNest()
    # window = TreeviewWidgetSelectProve()
    window.resize(320, 240)
    # window.show();
    window.setWindowTitle(
         QApplication.translate("toplevel", "Top-level widget"))
    # window.add_cols()

    sys.exit(app.exec_())

treeview_nest.ui 可用。

您在下图中看到项目child 没有显示按钮,并且其父级按钮被覆盖。显然我不知道如何为它编写代码。


更新)我想出了如何为孩子添加小部件。够棘手的是,使用QStandardItem.insertRow 结合索引就可以了。在我上面的示例代码中,将_add_widget 替换为以下内容:

    def _add_widget(self, n):
        item_toplevel = QStandardItem('{}th item'.format(n))
        self._datamodel.setItem(n, 0, item_toplevel)

        widget_toplevel = QPushButton('{}th button'.format(n))
        qindex_toplevel = self._datamodel.index(n, 1, QModelIndex())
        self.setIndexWidget(qindex_toplevel, widget_toplevel)

        if n == 2:
            item_child_col0 = QStandardItem('child col0')
            item_child_col1 = QStandardItem('child col1')
            #item_toplevel.appendRow(item_child_col0)

            item_toplevel.insertRow(0, [item_child_col0, item_child_col1])

            widget_child = QPushButton('child widget')
            qindex_child = item_child_col1.index()
            self.setIndexWidget(qindex_child, widget_child)

我确信这不是最佳/理想的设计方式,但似乎对我有用。在受到@Phlucious 回答的启发后,我提出了这个想法。谢谢!

【问题讨论】:

    标签: qt4 pyqt qtreeview qabstractitemmodel


    【解决方案1】:

    你的错误在这一行:

    qindex_widget_child = self._datamodel.index(n, 1, QModelIndex())
    self.setIndexWidget(qindex_widget_child, node_widget_child)
    

    它为您提供模型的第 2 行第 1 列的索引,这是“第 2 项”,而不是您的孩子。您的孩子位于std_item 的第 1 行第 1 列。在 Qt 中,尤其是在 QStandardItemModel 中,Children 是相对于它们的 parent 而存储的,而不是相对于模型。

    我对 PyQt 不够熟悉,无法为您提供确切的代码,但您应该能够执行以下操作:

    qindex_widget_child = std_item_child.index(QModelIndex())
    self.setIndexWidget(qindex_widget_child, node_widget_child)
    

    或者像这样:

    qindex_widget_child = std_item.child(0, 1).index(QModelIndex())
    self.setIndexWidget(qindex_widget_child, node_widget_child)
    

    【讨论】:

    • 谢谢,我最终选择了你的答案,因为我受到启发并在修改我的问题时想出了一个解决方法。评论你的想法,不幸的是,没有一个工作;前者在第0列添加小部件。后者中的方法不存在(pyqt主要遵循C++ api)。
    • 我再次查看了代码并将第二个选项修改为希望更有可能工作的东西。我对那个有点草率。很高兴你能得到一些有用的东西!
    • 您的解决方案或多或少是我在 c++ 中所做的,所以我不会真的说它草率。我对您是否可以在不先在那里分配孩子的情况下调用 child(0,1) 函数有点模糊!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多