【问题标题】:PyQT5 Data/View model representation with a complex widget具有复杂小部件的 PyQT5 数据/视图模型表示
【发布时间】:2021-05-22 01:34:25
【问题描述】:

我正试图围绕 PyQT5 上的一些 ModelView。

我有一个 QListView,它可以显示存储在 QAbstractListModel 中的数据。

但我希望 QListView 的每一行都显示在 QDesigner 中创建的复杂 Widget。

我创建了一个带有 QLabel、间隔和 QPushButton 的小部件。

我想让我的 QListView 的每个元素都使用这个小部件来显示我的模型数据

这是一个简单的ModelView QListView的基本代码

import typing
from PyQt5 import QtCore
from PyQt5.QtCore import QModelIndex, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QListView


class MyListModel(QtCore.QAbstractListModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.data_list = []

    def data(self, index: QModelIndex, role: int = ...) -> typing.Any:
        if role == Qt.DisplayRole:
            return self.data_list[index.row()]

    def rowCount(self, parent: QModelIndex = ...) -> int:
        return len(self.data_list)

data = ["emotion", "unliving", "brutally", "torch", "donut", "comet"]

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    layout = QWidget()
    layout.setLayout(QVBoxLayout())

    list_view = QListView()
    model = MyListModel()
    model.data_list = data
    list_view.setModel(model)

    layout.layout().addWidget(list_view)

    layout.resize(640, 480)
    layout.show()
    sys.exit(app.exec_())

我尝试创建一个 QStyledItemDelegate,并在模型上设置委托,但我无法使其工作。

class LineDelegate(QStyledItemDelegate):
    def __init__(self, parent):
        QStyledItemDelegate.__init__(self, parent)
        self.line = Ui_Form()
        self.line.setupUi(parent)

    def paint(self, painter: QtGui.QPainter, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> None:
    # Not sure what to put here 

文档似乎说应该使用委托来编辑视图内的数据,而不是复杂的小部件视图。

https://doc.qt.io/qtforpython/overviews/model-view-programming.html#a-simple-delegate

有什么可以得到我想要的吗?

我真的不知道如何处理这个。

【问题讨论】:

  • 通常情况下,使用委托是首选。您尝试过哪些无法“使其发挥作用”的方法?
  • 我尝试在委托中实例化小部件,但关于绘制方法,我不确定如何做到这一点“好方法”。我已经在主帖中添加了代码。出于性能考虑,QT 不建议在绘制方法中实例化

标签: python pyqt pyqt5


【解决方案1】:

您必须使用委托,以便为每个项目创建一个编辑器,然后使用 openPersistentEditor 方法打开编辑器,无需重写paint方法。

import typing

from PyQt5.QtCore import QAbstractListModel, QModelIndex, Qt
from PyQt5.QtWidgets import (
    QApplication,
    QListView,
    QStyledItemDelegate,
    QVBoxLayout,
    QWidget,
)


class Form(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)


class MyListModel(QAbstractListModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._data_list = []

    def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> typing.Any:
        if role == Qt.DisplayRole:
            return self._data_list[index.row()]

    def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
        return len(self._data_list)

    @property
    def data_list(self):
        return self._data_list

    @data_list.setter
    def data_list(self, data_list):
        self.beginResetModel()
        self._data_list = data_list.copy()
        self.endResetModel()


class Delegate(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        return Form(parent)

    """def setEditorData(self, editor, index):
        editor.label.setText(index.data())"""


data = ["emotion", "unliving", "brutally", "torch", "donut", "comet"]

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)

    list_view = QListView()
    model = MyListModel()
    model.data_list = data
    list_view.setModel(model)
    delegate = Delegate(list_view)
    list_view.setItemDelegate(delegate)

    for i in range(model.rowCount()):
        index = model.index(i, 0)
        list_view.openPersistentEditor(index)

    container = QWidget()
    layout = QVBoxLayout(container)
    layout.addWidget(list_view)
    container.resize(640, 480)
    container.show()
    sys.exit(app.exec_())

【讨论】:

  • 似乎不起作用,让我的窗口将每一行显示为文本。 openPersistentEditor 的意义何在?是否有必要强制创建委托编辑器?如果未注释,您评论的“setEditorData”会使代码根本无法运行,我会继续挖掘
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 2010-11-16
  • 2015-04-14
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多