从QStyledItemDelegate子类

时间:2017-04-08 18:06:53

标签: python pyqt qt5 pyqt5

在检查更复杂的setting中项目委托编辑器的生命周期问题的不同问题的过程中,当从QStyledItemDelegate子类调用时,我偶然发现了QColorDialog的奇怪行为。

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor,QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (
    QAbstractItemView, QApplication, QColorDialog,
    QGridLayout, QStyledItemDelegate, QTableView, QWidget
)


class ItemDelegate(QStyledItemDelegate):

    def createEditor(self, parent, option, index):
        if index.column() == 1:
            return QColorDialog(parent)
            #return QColorDialog(parent.parent())
            #return QColorDialog()
        else:
            return super(ItemDelegate, self).createEditor(parent, option, index)

    def setEditorData(self, editor, index):
        if index.column() == 1:
            value = index.model().data(index, Qt.EditRole)
            color = QColor(value)
            editor.setCurrentColor(color)
            editor.show()
        else:
            super(ItemDelegate, self).setEditorData(editor, index)

    def setModelData(self, editor, model, index):
        if index.column() == 1:
            color = editor.currentColor()
            model.setData(index, color, Qt.EditRole)
        else:
            super(ItemDelegate, self).setModelData(editor, model, index)

    def updateEditorGeometry(self, editor, option, index):
        if index.column() == 1:
            pass
        else:
            super(ItemDelegate, self).updateEditorGeometry(editor, option, index)


class ColorItem(QStandardItem):

    def __init__(self, color):
        super(ColorItem, self).__init__()
        self.setData(color)

    def setData(self, value, role = Qt.EditRole):
        if role == Qt.EditRole and isinstance(value, QColor):
            super(ColorItem, self).setData(value, Qt.DecorationRole)
        super(ColorItem, self).setData(value, role)

    def type(self):
        return QStandardItem.UserType + 234


class Window(QWidget):

    def __init__(self, parent = None):
        super(Window, self).__init__(parent)
        self.setWindowTitle("Item Delegate")

        data = [
            # label, rgb
            [ 'color', (0, 139, 139)],
            [ 'color', (255, 215, 0)],
        ]

        # create model, view, and delegate
        self.model = model = QStandardItemModel(len(data), 2)
        tableView = QTableView()
        tableView.setModel(model)
        delegate = ItemDelegate()
        tableView.setItemDelegate(delegate)
        tableView.horizontalHeader().setStretchLastSection(True)
        tableView.setEditTriggers(
            QAbstractItemView.EditKeyPressed |
            QAbstractItemView.DoubleClicked |
            QAbstractItemView.SelectedClicked)

        # fill model with data
        for row, (label, rgb) in enumerate(data):
            # column 0
            model.setItem(row, 0, QStandardItem(label))
            # column 1
            model.setItem(row, 1, ColorItem(QColor(*rgb)))
            #index = model.index(row, 1, QModelIndex())
            #tableView.openPersistentEditor(index)

        # finalize window
        layout = QGridLayout()
        layout.addWidget(tableView, 0, 0)
        self.setLayout(layout)
        self.resize(400, 200)

    def result(self):
        model = self.model
        for row in range(model.rowCount()):
            label = model.item(row, 0).data(Qt.EditRole)
            value = model.item(row, 1).data(Qt.EditRole)
            print('[%s] %s: %s' % (row, label, value.getRgb()[:3]))


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    ret = app.exec_()
    window.result()
    sys.exit(ret)

执行此脚本时,双击颜色项会显示标准QColorDialog。如果移动,对话框将立即关闭。 OTOH,如果事先选择任意颜色,则对话框是可移动的。

需要对此行为进行解释。

此生命周期问题与底层QStyledItemDelegate小部件有关。表视图上的焦点更改可能会导致创建的编辑器窗口小部件被破坏,但为什么选择颜色会有所不同呢?我已经为QColorDialog尝试了不同的父母,但行为仍然存在,所以它闻起来就像一个问题,在对话框本身内部。

Environment:
Python: 3.4.5
Sip: 4.19.2
Qt5: 5.8.0
PyQt5: 5.8.2
Linux: openSUSE/KDE4

0 个答案:

没有答案