【问题标题】:QComboBox show whole row of QTreeViewQComboBox 显示整行 QTreeView
【发布时间】:2021-02-17 11:26:56
【问题描述】:

我想使用 QtreeView 来组织 QComboBox 显示的数据。正如您在我的示例中看到的那样,到目前为止,创建框和设置数据都有效。 但我的问题是,组合框本身只显示第一个参数而不是整行。我想要的是,显示整行,而不仅仅是行的第一项。

这可能与每个单元格都是可选的事实有关吗?是不是一定要禁止选择树枝末端的项目?

如何在将元素添加到 QtreeView-data 时实现这一点?

最小的例子:

import sys

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


data = [['a','b','c'],['d','e','f'],['g','h','i']]

class MainWindow(QMainWindow):
    dispatcher = 0

    def __init__(self):
        super().__init__()
        # buil UI
        self.init_ui()

    def init_ui(self):
        # layout
        self.box_window = QVBoxLayout()
        # content
        model = QStandardItemModel(len(data),len(data[0]))
        row = 0
        for r in data:
            col = 0
            for item in r:
                model.setData(model.index(row, col), item)
                col += 1
            row += 1
        tree_view = QTreeView()
        tree_view.setHeaderHidden(True)
        tree_view.setRootIsDecorated(False)
        tree_view.setAlternatingRowColors(True)
        combobox = QComboBox()
        combobox.setMinimumSize(250,50)
        combobox.setView(tree_view)
        combobox.setModel(model)
        self.box_window.addWidget(combobox)
        self.box_window.addStretch()
        # build central widget and select it
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.centralWidget().setLayout(self.box_window)

        # show window
        self.setGeometry(50,50,1024,768)
        self.setWindowTitle("Test")
        self.show()

def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

【问题讨论】:

  • QComboBox 不直接支持使用树视图;它可以通过适当的实现来完成,但无论如何,您的模型不是树,所以使用这样的视图没有意义。虽然可以使用 QTableView 来代替,但是由于您想显示整行的内容,那也没有意义。
  • 所以组合框“子视图”的元素如何组织并不重要,组合框只能显示确切的一项?使用 ListView 而不是 TreeView 怎么样?是否可以构建一个看起来像表格行的 ListItem?数据垂直对齐很重要。
  • 我的印象是你有一个XY problem。您能否尝试更好地解释组合框模型的实际目的是什么?例如,您需要在其他视图中使用模型,还是需要从其他地方单独访问模型列?还是您只需要显示一些需要在“列”中水平对齐的格式的数据?
  • 此组合框旨在从一组项目中选择一个项目。每个项目本身都有几个属性。为了选择最合适的项目,我想列出所有项目(行)的所有属性(列)。想象一下,您正在寻找螺丝。然后组合框列表将包含您拥有的所有螺钉。现在您要选择正确的。因此,您单击该框,查看所有螺钉及其属性(直径、长度、头部类型、材料……)的列表,当您找到正确的并选择它时,该框会显示您的属性选定的螺丝。
  • 这与eyallesc's answer 没有太大变化:如果您想以固定间距显示项目在组合框中(不是它的视图),您需要一个更复杂的实现完全取决于 如何 您希望显示它们,也因为 QComboBox 根据项目内容设置/更新其大小。

标签: python pyqt5


【解决方案1】:

一种可能的解决方案是将行中的文本连接起来并设置为要绘制的文本:

class ComboBox(QComboBox):
    def paintEvent(self, event):
        painter = QStylePainter(self)
        painter.setPen(self.palette().color(QPalette.Text))
        # draw the combobox frame, focusrect and selected etc.
        opt = QStyleOptionComboBox()
        self.initStyleOption(opt)

        values = []

        for c in range(self.model().columnCount()):
            index = self.model().index(self.currentIndex(), c, self.rootModelIndex())
            values.append(index.data())
        opt.currentText = " ".join(values)
        painter.drawComplexControl(QStyle.CC_ComboBox, opt)
        # draw the icon and text
        painter.drawControl(QStyle.CE_ComboBoxLabel, opt)

【讨论】:

  • 以及如何垂直对齐元素?当仅通过空格连接元素时,不同的元素长度将导致未垂直对齐的列表。它应该看起来像后面有一个网格
  • @paul_schaefer 这真的很复杂,因为你需要计算每个项目的大小,我只限于给你一个简单的实现:-(
猜你喜欢
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 2018-06-22
  • 2023-03-17
  • 2021-06-27
相关资源
最近更新 更多