QStyledItemDelegate 绘制刷新问题 [英] QStyledItemDelegate paint refresh issues

查看:165
本文介绍了QStyledItemDelegate 绘制刷新问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试围绕模型视图方法编写一个缩略图查看器应用程序.

I am currently trying to wrap my head around the model-view approach and write a thumbnail viewer application.

在这个例子中,我只是尝试绘制 20 个框,但我得到了一个随机选择,它会随着鼠标移动而更新.滚动使事情变得更糟,有时绘图只有框等.而且文本似乎根本没有呈现.

In this example I simply try to draw 20 boxes, but I get what seems like a random selection which updates on mouse movement. Scrolling makes things even worse and draws sometimes only have the boxes etc. Also the text seems to be not rendered at all.

对我来说,它看起来像是paint方法的刷新/更新问题.我在这里遗漏了什么吗?

To me it looks like a refresh/update problem of the paint method. Am I missing something here?

最终我需要展示很多项目.所有都包含一些标签和一个需要在运行时更新的像素图.所以我认为画它们将是最快的解决方案.或者我尝试在paint方法中渲染我的小部件:

Ultimately I need to display a lot of items. All containing a few labels and a pixmap which needs to be updated at runtime. So I thought painting them would be the fastest solution. Alternatively I tried rendering my widgets in the paint method with:

customWidget.render(painter, QtCore.QPoint(0,0), renderFlags=QtGui.QWidget.DrawChildren)

这似乎更慢,但至少可以工作.

which seems to be slower, but at least working.

这是一个最小的工作示例来说明我的问题:

Here is a minimal working example to illustrate my problem:

import sys
from PySide import QtCore
from PySide import QtGui

elements = range(20)

class ElementListModel(QtCore.QAbstractListModel):
    def __init__(self, elements = [], parent = None):
        super(ElementListModel, self).__init__()
        self.__elements = elements

    def rowCount(self, parent):
        return len(self.__elements)

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return str(self.__elements[index.row()])

class ElementThumbDelegate(QtGui.QStyledItemDelegate):
    def __init__(self, view, parent=None):
        super(ElementThumbDelegate, self).__init__(parent)

    def paint(self, painter, options, index):

        width = options.rect.width()
        height = options.rect.height()

        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtGui.QColor(255, 255, 255))
        painter.setBrush(QtGui.QColor(10, 10, 10))
        painter.drawRect(0, 0, width, height)
        painter.drawText(options.rect, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter, str(index.data()))
        painter.translate(options.rect.topLeft())

    def sizeHint(self, options, index):
        return QtCore.QSize(50, 50)

def main():
    app = QtGui.QApplication(sys.argv)
    viewer = QtGui.QListView()

    viewModel = ElementListModel(elements)
    viewer.setModel(viewModel)
    viewer.setViewMode(QtGui.QListView.IconMode)
    viewer.setItemDelegate(ElementThumbDelegate(viewer))

    viewer.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

提前致谢.任何帮助或指示下一步去哪里将不胜感激!

Thanks in advance. Any help or pointers where to look next would be highly appreciated!

推荐答案

事实证明 painter.translate() 结合在查看器原点 (0,0) 处绘制框正在战斗自动定位并导致问题.

It turns out that painter.translate() in combination with drawing the box at the viewer origin (0,0) was fighting the auto positioning and causing the problem.

委托到适当位置的翻译是由视图本身处理的——不需要手动完成.

The translation of the delegate to the appropriate position is handled by the view itself - there is no need to do it manually.

工作代码:

import sys
from PySide import QtCore
from PySide import QtGui

elements = range(20)

class ElementListModel(QtCore.QAbstractListModel):
    def __init__(self, elements = [], parent = None):
        super(ElementListModel, self).__init__()
        self.__elements = elements

    def rowCount(self, parent):
        return len(self.__elements)

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return str(self.__elements[index.row()])

class ElementThumbDelegate(QtGui.QStyledItemDelegate):
    def __init__(self, view, parent=None):
        super(ElementThumbDelegate, self).__init__(parent)

    def paint(self, painter, options, index):
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtGui.QColor(255, 255, 255))
        painter.setBrush(QtGui.QColor(10, 10, 10))
        painter.drawRect(options.rect)
        painter.drawText(options.rect, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter, str(index.data()))

    def sizeHint(self, options, index):
        return QtCore.QSize(50, 50)

def main():
    app = QtGui.QApplication(sys.argv)
    viewer = QtGui.QListView()

    viewModel = ElementListModel(elements)
    viewer.setModel(viewModel)
    viewer.setViewMode(QtGui.QListView.IconMode)
    viewer.setItemDelegate(ElementThumbDelegate(viewer))

    viewer.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

这篇关于QStyledItemDelegate 绘制刷新问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆