QStyledItemDelegate проблемы обновления краски

В настоящее время я пытаюсь обернуть голову вокруг подхода просмотра модели и написать приложение для просмотра миниатюр.

В этом примере я просто пытаюсь нарисовать 20 блоков, но я получаю то, что кажется случайным выбором, который обновляется при движении мыши. Прокрутка делает вещи еще хуже, а на рисовании иногда появляются только прямоугольники и т. Д. Кроме того, кажется, что текст вообще не отображается.

Для меня это выглядит как проблема обновления / обновления метода рисования. Я что-то здесь упускаю?

проблема с краской

В конечном итоге мне нужно отобразить много предметов. Все содержат несколько меток и растровое изображение, которое необходимо обновить во время выполнения. Поэтому я подумал, что покрасить их будет самым быстрым решением. В качестве альтернативы я попытался отрисовать свои виджеты в методе рисования с помощью:

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

что, кажется, медленнее, но, по крайней мере, работает.

Вот минимальный рабочий пример, чтобы проиллюстрировать мою проблему:

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()

Заранее спасибо. Любая помощь или указатели, где искать дальше будет высоко ценится!

1 ответ

Решение

Оказывается, что painter.translate() в сочетании с рисованием прямоугольника в начале координат зрителя (0,0) боролся с автоматическим позиционированием и вызывал проблему.

Перевод делегата на соответствующую позицию обрабатывается самим представлением - нет необходимости делать это вручную.

Рабочий код:

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()
Другие вопросы по тегам