Использование QStyledItemDelegates в качестве пользовательских элементов в QListView - PullRequest
0 голосов
/ 23 октября 2019

Я хочу создать собственный виджет ListView, который имеет пользовательские элементы, подобные этому: https://i.stack.imgur.com/iTNbN.png

Однако в документации qt и некоторых сообщениях stackoverflow говорится, что в идеале следует использовать QStyleItemDelegate. Я никогда раньше не работал с «делегатами», но насколько я понял из моих исследований, они вызывались ListView для рисования / рендеринга каждого элемента.

Я нашел пример делегата в другом проекте (https://github.com/pyblish/pyblish-lite/blob/master/pyblish_lite/delegate.py) и они рисуют все вручную /, по сути, восстанавливают целые виджеты, рисуя прямоугольники.

Мне кажется, что это немного непрактично, поскольку большую часть времени пользовательские виджеты элементов могут быть составными частями существующих виджетов. Снимок экрана выше. Он по существу содержит Qlabel, QPixmap и четыре DoubleSpinBoxes.

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

Например, первый ListViewItem должен передать данные модели делегату, чтобы текст self.lightGroupName QLabel могустановить на «Light1».

Любая помощьочень признателен, так как я понятия не имею, как дальше отсюда:

from PySide2 import QtCore, QtGui, QtWidgets

class LightDelagate(QtWidgets.QStyledItemDelegate): #custom item view
    def __init__(self, parent=None):
        super(LightDelagate, self).__init__(parent)
        self.setupUI()

    def setupUI(self):
        self.masterWidget = QtWidgets.QWidget()

        #Light Group Header 
        self.hlayLightHeader = QtWidgets.QHBoxLayout()
        self.lightGroupName = QtWidgets.QLabel("Checker")
        self.hlayLightHeader.addWidget(self.lightGroupName)

        #Light AOV Preview
        self.lightPreview = QtWidgets.QLabel()
        #set size 
        self.aovThumbnail = QtGui.QPixmap(180, 101)
        #self.lightPreview.setPixmap(self.aovThumbnail.scaled(self.lightPreview.width(), self.lightPreview.height(), QtCore.Qt.KeepAspectRatio))

        # #Color Dials
        # self.hlayColorDials = QtWidgets.QHBoxLayout()
        # self.rgbDials = QtWidgets.QHBoxLayout()
        # self.rDial = QtWidgets.QDoubleSpinBox()
        # self.rDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
        # self.gDial = QtWidgets.QDoubleSpinBox()
        # self.gDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
        # self.bDial = QtWidgets.QDoubleSpinBox()
        # self.bDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
        # self.rgbDials.addWidget(self.rDial)
        # self.rgbDials.addWidget(self.gDial)
        # self.rgbDials.addWidget(self.bDial)
        # #Exposure
        # self.hlayExposureDials = QtWidgets.QHBoxLayout()
        # self.exposureDial = QtWidgets.QDoubleSpinBox()
        # self.exposureDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)

        # self.hlayExposureDials.addWidget(self.exposureDial)
        # self.hlayColorDials.addLayout(self.rgbDials)
        # self.hlayColorDials.addLayout(self.hlayExposureDials)

        #entire layout
        self.vlayWidget = QtWidgets.QVBoxLayout()
        self.vlayWidget.addLayout(self.hlayLightHeader)
        self.vlayWidget.addWidget(self.lightPreview)
        # self.vlayWidget.addLayout(self.hlayColorDials)
        self.vlayWidget.setContentsMargins(2,2,2,2)
        self.vlayWidget.setSpacing(2)
        self.masterWidget.setLayout(self.vlayWidget)



    def paint(self, painter, option, index):
        rowData = index.model().data(index, QtCore.Qt.DisplayRole)
        self.lightGroupName.setText(rowData[0])
        print (option.rect)
        painter.drawRect(option.rect)
        painter.drawText()
    def sizeHint(self, option, index):
        return QtCore.QSize(200, 150)

class LightListModel(QtCore.QAbstractListModel): #data container for list view
    def __init__(self, lightList= None):
        super(LightListModel, self).__init__()
        self.lightList = lightList or []

    #reimplement
    def rowCount(self, index):
        return len(self.lightList)

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


class LightListView(QtWidgets.QListView): #
    def __init__(self):
        super(LightListView, self).__init__()
        self.setFlow(QtWidgets.QListView.LeftToRight)
        self.setItemDelegate(LightDelagate(self))
        self.setMinimumWidth(1880)

lightListTest = [ 
    ('Light1' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
    ('Light2' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
    ('Light3' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
    ('Light4' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)})
]

app = QtWidgets.QApplication([])
LLV = LightListView()
model = LightListModel(lightList=lightListTest)
LLV.setModel(model)
LLV.show()
LLV.setSe
app.exec_()

1 Ответ

0 голосов
/ 24 октября 2019

Вместо QListView, вы могли бы использовать QListWidget и переопределить itemWidget? Идея состоит в том, что это позволяет вам возвращать QWidget (с дочерними элементами согласно вашему скриншоту) вместо того, чтобы реализовывать QStyledItemDelegate, который вызывает метод paint каждого дочернего виджета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...