QTreeWidget PyQt 中出现额外的行

Posted

技术标签:

【中文标题】QTreeWidget PyQt 中出现额外的行【英文标题】:Extra row appearing in QTreeWidget PyQt 【发布时间】:2021-12-20 15:34:29 【问题描述】:

我有一段代码,其中我将两个子项添加到 QTreeWidget 父项。子项设置为“可编辑”。

我在这里面临两个问题:

    出现了一个带有 可编辑项目的额外行。 (我希望“Min”和“Max”在同一行)

    如果我将可编辑项目更改为 空字符串,那么它看起来好像什么都没有,我想要某种高亮显示这里有一个空字段(某种一个盒子)

如何解决这些问题?

代码:

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

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.FilterList = QTreeWidget()
        self.setCentralWidget(self.FilterList)
        self.setWindowTitle("Form")
        self.setGeometry(50,50,800,500)
        self.generateData()

    def generateData(self):
        self.FilterList.setColumnCount(3)
        self.FilterList.setHeaderLabels(["Filter Questions"])
        DifficultyNode = QTreeWidgetItem(["Difficulty"])
        self.FilterList.addTopLevelItem(DifficultyNode)
        self.FilterList.itemChanged.connect(self.handleItemChanged)
        EasyNode = QTreeWidgetItem(["Easy"])
        EasyNode.setCheckState(0, Qt.Unchecked)
        NormalNode = QTreeWidgetItem(["Normal"])
        NormalNode.setCheckState(0, Qt.Unchecked)
        HardNode = QTreeWidgetItem(["Hard"])
        HardNode.setCheckState(0, Qt.Unchecked)
        HardNode.setFlags(HardNode.flags() | QtCore.Qt.ItemIsEditable)
        MinNode = QTreeWidgetItem()
        MinNode.setText(1, "Min")
        MinNode.setFlags(MinNode.flags() | QtCore.Qt.ItemIsEditable)
        MaxNode = QTreeWidgetItem()
        MaxNode.setText(2, "Max")
        MaxNode.setFlags(MaxNode.flags() | QtCore.Qt.ItemIsEditable)
        
        DifficultyNode.addChild(EasyNode)
        EasyNode.addChild(MinNode)
        EasyNode.addChild(MaxNode)
        DifficultyNode.addChild(NormalNode)
        DifficultyNode.addChild(HardNode)
        

    def handleItemChanged(self, item, column):
        if item.checkState(column) == QtCore.Qt.Checked:
            print('Item Checked', item.text(column))
        elif item.checkState(column) == QtCore.Qt.Unchecked:
            print('Item Unchecked', item.text(column))

def main():
    app = QApplication(sys.argv)
    form = MainWindow()
    form.show()
    app.exec_()

main()

【问题讨论】:

错字:MinNode.setText(2, "Max") --> MaxNode.setText(2, "Max") ? @G.M.感谢您指出错字,但看起来还是差不多。 不仅是编辑的时候,删除“Min”或“Max”的文字,项目被取消选择的时候也会出现一个框。 @alec 是的,我明白了很多。可能问题不够清楚。我不想在第一列中有一个框。我只想要它only over the items which are editable(在这种情况下是“Min”和“Max”),从一开始也是如此。 @alec 我希望用户真正知道他必须在哪里输入/编辑值。在这种情况下,当我删除“Min”、“Max”时,最终用户将永远无法知道他必须在哪里输入值。 【参考方案1】:

要在同一行上获取“Min”和“Max”,请仅使用一个 QTreeWidgetItem 并为两列设置文本。

如果您想要一个永久框,一个选项是将 QTreeWidgetItem 的 itemWidget 设置为 QLineEdit 并连接其 editingFinished 以设置项目文本。

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.FilterList = QTreeWidget()
        self.setCentralWidget(self.FilterList)
        self.setWindowTitle("Form")
        self.setGeometry(50,50,800,500)
        self.generateData()

    def generateData(self):
        self.FilterList.setColumnCount(3)
        self.FilterList.setHeaderLabels(["Filter Questions"])
        DifficultyNode = QTreeWidgetItem(["Difficulty"])
        self.FilterList.addTopLevelItem(DifficultyNode)
        self.FilterList.itemChanged.connect(self.handleItemChanged)
        EasyNode = QTreeWidgetItem(["Easy"])
        EasyNode.setCheckState(0, Qt.Unchecked)
        NormalNode = QTreeWidgetItem(["Normal"])
        NormalNode.setCheckState(0, Qt.Unchecked)
        HardNode = QTreeWidgetItem(["Hard"])
        HardNode.setCheckState(0, Qt.Unchecked)
        HardNode.setFlags(HardNode.flags() | QtCore.Qt.ItemIsEditable)
        MinNode = QTreeWidgetItem()
        
        DifficultyNode.addChild(EasyNode)
        EasyNode.addChild(MinNode)
        DifficultyNode.addChild(NormalNode)
        DifficultyNode.addChild(HardNode)

        self.setTextBox(MinNode, 1, "Min")
        self.setTextBox(MinNode, 2, "Max")

    def setTextBox(self, item, column, text):
        box = QLineEdit(text)
        box.editingFinished.connect(lambda: item.setText(column, box.text()))
        self.FilterList.setItemWidget(item, column, box)

    def handleItemChanged(self, item, column):
        if item.checkState(column) == QtCore.Qt.Checked:
            print('Item Checked', item.text(column))
        elif item.checkState(column) == QtCore.Qt.Unchecked:
            print('Item Unchecked', item.text(column))

【讨论】:

能否请您告诉我如何突出显示可编辑文本字段?在当前场景中,文本更改为空字符串的那一刻,它给最终用户一种感觉,好像那里什么都不存在。 @deepanshu 查看修订版 请看上面的“UPDATE”,解决方案似乎不对。 @deepanshu 查看修改后的 #2 是的,现在它可以正常工作了。非常感谢。

以上是关于QTreeWidget PyQt 中出现额外的行的主要内容,如果未能解决你的问题,请参考以下文章

Python(PyQT):如何在没有最后一个孩子的 QTreeWidget 中插入 XML 文件

在 PyQt 中将 QTreeWidget 转换为嵌套字典

在 PyQt 中使用拖放重新排序 QTreeWidget 中的项目

PyQt4 中的多列(可能使用 QTreeWidget)

在 PyQt QTreeWidget 中移动节点位置

在PyQt5中的QTreeWidget和QListWidget之间拖动项目?