如何将多个组合框作为子级添加到QTreeWidgetItem

问题描述 投票:0回答:1

我处于一种情况,我需要根据随机不同数量的父母和随机数量的嵌套孩子来动态生成UI。

当子QTreeWidgetItem展开时,其子项应如下所示:

-Parent
    -Child
        -ComboBox | ComboBox | ComboBox | ComboBox

我一直在尝试setItemWidget,但没有运气,只会崩溃。下面是我尝试做的一个简单示例。

#! /usr/bin/env python

from PySide2 import QtWidgets, QtCore


class TestUI(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(TestUI, self).__init__(parent)

    def setup_UI(self):
        # Setup the main window
        self.MainWindow = QtWidgets.QMainWindow(self.parent)
        self.MainWindow.resize(900, 400)
        self.MainWindow.setMinimumSize(QtCore.QSize(900, 600))
        self.MainWindow.setObjectName("TestUI")

        # Create the main tree
        self.tree_widget = QtWidgets.QTreeWidget(self.MainWindow)
        self.gridLayout = QtWidgets.QGridLayout(self.tree_widget)
        self.MainWindow.setCentralWidget(self.tree_widget)

        # Create a root parent item, repeat this for as many parents as needed
        top_item = QtWidgets.QTreeWidgetItem(self.tree_widget)
        top_item.setText(0, "Top_Parent_Item")
        self.tree_widget.addTopLevelItem(top_item)

        # Create child item
        child_item = QtWidgets.QTreeWidgetItem(top_item)
        child_item.setText(0, "Child_Item")
        top_item.addChild(child_item)

        # Create the child to the child that we use to replace the item with the combobox widget
        nested_child_item = QtWidgets.QTreeWidgetItem(child_item)
        nested_child_item.setText(0, "Nested_Child_Item")
        child_item.addChild(nested_child_item)

        # Create the combobox widget for all comboxes
        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(widget)

        # Repeat this 4 times for 4 comboboxes
        combo_box_1 = QtWidgets.QComboBox()
        values = ["1", "2", "3", "4", "5"]
        combo_box_1.addItems(values)
        layout.addWidget(combo_box_1)

        # Apply layout with everything in it
        widget.setLayout(layout)

        # This line hard crashes my code but no idea how else to go about adding a widget to an item.
        self.tree_widget.setItemWidget(nested_child_item, 1, combo_box_1)

        #Show the UI
        self.MainWindow.show()

# Launch UI
test = TestUI()
test.setup_UI()
python python-2.7 pyside2 qcombobox qtreewidget
1个回答
1
投票

在回答您的问题之前,应注意代码中存在许多不一致之处:您有一个QMainWindow是另一个QMainWindow的子级,有一些无用的小部件,等等。我建议您对代码进行仔细分析是否有意义。

另一方面,默认的QTreeWidget具有一列,因此您只能设置QComboBox,并且列的索引从0开始。如果要显示更多列,则必须显式设置它。

#! /usr/bin/env python

from PySide2 import QtWidgets, QtCore


class TestUI(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(TestUI, self).__init__(parent)

    def setup_UI(self):
        # Create the main tree
        self.tree_widget = QtWidgets.QTreeWidget()
        self.setCentralWidget(self.tree_widget)

        self.tree_widget.setColumnCount(4)

        top_item = QtWidgets.QTreeWidgetItem(self.tree_widget)
        top_item.setText(0, "Top_Parent_Item")
        self.tree_widget.addTopLevelItem(top_item)

        child_item = QtWidgets.QTreeWidgetItem(top_item)
        child_item.setText(0, "Child_Item")
        top_item.addChild(child_item)

        nested_child_item = QtWidgets.QTreeWidgetItem(child_item)
        nested_child_item.setText(0, "Nested_Child_Item")
        child_item.addChild(nested_child_item)

        for i in range(self.tree_widget.columnCount()):
            combo_box = QtWidgets.QComboBox(self.tree_widget)
            values = ["1", "2", "3", "4", "5"]
            combo_box.addItems(values)

            self.tree_widget.setItemWidget(nested_child_item, i, combo_box)

        self.tree_widget.expandAll()
        self.resize(640, 480)

        self.show()


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    test = TestUI()
    test.setup_UI()
    app.exec_()

enter image description here

更新:

另一个可能的解决方案是使用委托来自动提供QComboBox:

#! /usr/bin/env python

from PySide2 import QtWidgets, QtCore


class StyledItemDelegate(QtWidgets.QStyledItemDelegate):
    def paint(self, painter, option, index):
        if index.parent().parent().isValid():
            if isinstance(option.widget, QtWidgets.QAbstractItemView):
                option.widget.openPersistentEditor(index)
        else:
            super(StyledItemDelegate, self).paint(painter, option, index)

    def createEditor(self, parent, option, index):
        if index.parent().parent().isValid():
            editor = QtWidgets.QComboBox(parent)
            values = ["1", "2", "3", "4", "5"]
            editor.addItems(values)
            return editor
        return super(StyledItemDelegate, self).createEditor(parent, option, index)

    def updateEditorGeometry(self, editor, option, index):
        editor.setContentsMargins(0, 0, 0, 0)
        editor.setGeometry(option.rect)

    def sizeHint(self, option, index):
        s = super(StyledItemDelegate, self).sizeHint(option, index)
        s.setHeight(s.height() * 1.5)
        return s


class TestUI(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(TestUI, self).__init__(parent)

    def setup_UI(self):
        # Create the main tree
        self.tree_widget = QtWidgets.QTreeWidget()
        self.setCentralWidget(self.tree_widget)

        delegate = StyledItemDelegate(self)
        self.tree_widget.setItemDelegate(delegate)
        self.tree_widget.setColumnCount(4)

        top_item = QtWidgets.QTreeWidgetItem(self.tree_widget)
        top_item.setText(0, "Top_Parent_Item")
        self.tree_widget.addTopLevelItem(top_item)

        child_item = QtWidgets.QTreeWidgetItem(top_item)
        child_item.setText(0, "Child_Item")
        top_item.addChild(child_item)

        nested_child_item = QtWidgets.QTreeWidgetItem(child_item)
        child_item.addChild(nested_child_item)

        self.tree_widget.expandAll()
        self.resize(640, 480)

        self.show()


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    test = TestUI()
    test.setup_UI()
    app.exec_()
© www.soinside.com 2019 - 2024. All rights reserved.