【问题标题】:QTreeWidget and QPainter combinationQTreeWidget 和 QPainter 组合
【发布时间】:2020-07-16 14:48:00
【问题描述】:

我对 QTreeWidget 有点迷失了,我无法从找到的主题中获取相关信息(例如:how to set QTreeView background image with QStyle::StandardPixmap in stylesheet method? 或 Python: PyQt QTreeview example - selection 或 Styling Qt QTreeView with CSS 或 Displaying tabular data in Qt5 ModelViews)。

我有两个文件,一个是gui,一个是工人阶级:

界面:

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")

        self.tree = QtWidgets.QTreeWidget(Dialog)
        self.tree.setGeometry(QtCore.QRect(10, 60, 760, 480))
        self.tree.setHeaderLabels(['circ', 'state', 'test'])
        self.tree.setSortingEnabled(True)

工人:

class AppWindow(QDialog):   
    def __init__(self, fullscreen=False):          
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.show()  


        self.timer = QTimer()
        self.timer.setInterval(500)
        self.timer.timeout.connect(self.refresh_gui) 
        self.timer.start()


    def refresh_gui(self):
        self.painter = QPainter(self)
        tmp = {0: {"state": 1, "info": "hello"}, 1: {"state": 0, "info": "world"}}          
        for i in tmp:
            if tmp[i]["state"] == 0:
                painter.setPen(QPen(Qt.red,  8, Qt.SolidLine))
            else:
                painter.setPen(QPen(Qt.green,  8, Qt.SolidLine))
            circ = painter.drawEllipse(2,2,20,20)

            item = QtWidgets.QTreeWidgetItem(self.ui.tree, [circ, tmp[i]["state"], "empty"])
            item.setText(2, "circ painted")

我想实现,如果state == 0 第一列中显示一个红色圆圈,如果state == 1 一个绿色圆圈。我不知道如何将 QTreeWidgetItem 交给 PyQt5.QtGui.QPainter 对象而不是字符串。

另外,我确实得到了错误:

QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::end: Painter not active, aborted

还有一些更低的行(因为它):QPainter::setPen: Painter not active 因为我打电话给self.painter = QPainter(self),这是在讨论in this git issue from matplotlib,但我没有在我的代码中修复它。我发现了这个QPainter tutorial,它在 QPixmap 上绘制,它也适用于我,但不是我在这里寻找的。

【问题讨论】:

  • 您得到的画家错误与 matplotlib 问题无关:您不能随时在小部件上调用 QPainter,因为它只能在 Qt 创建的 paintEvent 内完成(由系统请求“显示”小部件触发,或在调用update() 或repaint() 后触发)。如果要在项目视图中显示其他内容,则必须继承 QStyledItemDelegate 并覆盖其 paint() 方法。

标签: python-3.x pyqt5 qpainter qtreewidget


【解决方案1】:

小部件的绘制不是在任何方法中完成的,但是必须重写paintEvent方法,只要Qt需要或开发人员使用更新或重绘,就会调用该方法。但是对于处理从 QAbstractItemView 继承的模型(即大量有组织的信息)的类,如果要绘制项目,则必须使用委托。

综合以上,解决办法是:

class Delegate(QtWidgets.QStyledItemDelegate):
    def paint(self, painter, option, index):
        state = index.data(QtCore.Qt.UserRole)
        color = (
            QtGui.QColor(QtCore.Qt.red) if state == 0 else QtGui.QColor(QtCore.Qt.green)
        )
        painter.setPen(QtGui.QPen(color, 4, QtCore.Qt.SolidLine))
        diameter = min(option.rect.width(), option.rect.height())
        rect = QtCore.QRect(0, 0, diameter // 2, diameter // 2)
        rect.moveCenter(option.rect.center())
        painter.drawEllipse(rect)


class AppWindow(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.show()

        delegate = Delegate(self.ui.tree)
        self.ui.tree.setItemDelegateForColumn(0, delegate)

        self.timer = QtCore.QTimer(interval=500, timeout=self.refresh_gui)
        self.timer.start()

    @QtCore.pyqtSlot()
    def refresh_gui(self):

        tmp = [{"state": 1, "info": "hello"}, {"state": 0, "info": "world"}]

        for d in tmp:
            item = QtWidgets.QTreeWidgetItem(self.ui.tree, ["", str(d["state"]), "empty"])
            item.setData(0, QtCore.Qt.UserRole, d["state"])
            item.setText(2, "circ painted")

【讨论】:

  • 有效。谢谢你。我现在有两个问题:(1)paint 没有被调用,但是因为 Delegate 是 QStyledItemDelegate 类型,所以它被重新调用,对吗? (2) 为什么需要装饰器?
猜你喜欢
  • 1970-01-01
  • 2021-10-17
  • 2020-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 2011-10-19
  • 1970-01-01
相关资源
最近更新 更多