You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt QTreeWidget出现额外空白行及空编辑项无标识问题问询

PyQt QTreeWidget 问题修复方案

问题1:Min/Max字段分两行显示修复

你当前的代码给Min和Max分别创建了独立的QTreeWidgetItem对象,每个对象对应QTreeWidget的一行,所以会出现额外空白行。要放在同一行展示,只需把两个字段合并到同一个QTreeWidgetItem的不同列即可,同时开启对应列的编辑权限。

问题2:空可编辑项高亮提示修复

默认QTreeWidget单元格无内容时无特殊标识,我们可以通过自定义QStyledItemDelegate委托类,重写绘制方法,判断单元格文本为空时绘制高亮边框提示。

完整修改后代码

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

# 自定义委托,用于空单元格高亮
class EmptyItemHighlightDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        super().paint(painter, option, index)
        # 仅对可编辑且文本为空的单元格生效
        if index.flags() & Qt.ItemIsEditable and not index.data(Qt.DisplayRole):
            painter.save()
            # 可自行修改边框颜色、粗细调整提示效果
            pen = QPen(QColor(255, 0, 0), 1)
            painter.setPen(pen)
            painter.drawRect(option.rect.adjusted(0, 0, -1, -1))
            painter.restore()

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.FilterList = QTreeWidget()
        # 给树组件绑定自定义委托
        self.FilterList.setItemDelegate(EmptyItemHighlightDelegate())
        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", "Min", "Max"])
        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)
        
        # 合并Min、Max为同一个节点,实现同一行展示
        RangeNode = QTreeWidgetItem()
        RangeNode.setText(1, "Min")
        RangeNode.setText(2, "Max")
        RangeNode.setFlags(RangeNode.flags() | QtCore.Qt.ItemIsEditable)
        
        DifficultyNode.addChild(EasyNode)
        EasyNode.addChild(RangeNode)
        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()

可选调整说明

  • 若不需要红色边框,可修改委托中的绘制逻辑,替换为背景色高亮、虚线边框等其他提示样式
  • 若仅需要指定列做空值校验,可在委托的判断逻辑中增加index.column() == 1 or index.column() ==2的列过滤条件

内容的提问来源于stack exchange,提问作者Bond_007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 07:18:00