【问题标题】:QVariant alternative when migrating from PyQt5 to PySide2从 PyQt5 迁移到 PySide2 时的 QVariant 替代方案
【发布时间】:2019-09-30 17:56:27
【问题描述】:

由于以下代码,我在从 PyQt5 切换到 PySide2 时遇到了一些问题:

class EnumModel(QtCore.QAbstractListModel):

    def __init__(self, list_of_enums):
        """
        Enumeration model
        :param list_of_enums: list of enumeration values to show
        """
        QtCore.QAbstractListModel.__init__(self)
        self.items = list_of_enums

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.items)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid() is True:
            if role == QtCore.Qt.DisplayRole:
                return QtCore.QVariant(self.items[index.row()].value[0])
            elif role == QtCore.Qt.ItemDataRole:
                return QtCore.QVariant(self.items[index.row()].value[0])
        return QtCore.QVariant()

代码在 PyQt5 下运行良好。

在迁移过程中,我发现the official website 说:

PySide 仅支持 PyQt 的 API 2(请参阅 PSEP 101)了解详细信息。 因此,诸如 QStrings、QStringLists 和 QVariants 之类的 Qt 类是 在 PySide 上不可用。相反,您应该简单地使用本机 Python 数据类型。

所以解决方案是(我猜)将QVariant 简单地更改为str。当我这样做时,该类不会引发任何错误,但它也不会显示模型。

事实上,函数data 接收的是role=13 而不是role=QtCore.Qt.DisplayRole

我不知道这是 PySide2 的错误(在 Linux 下有点错误)还是其他原因。

一个最小可行的例子是这样的:

from PySide2.QtWidgets import *
from PySide2 import QtCore
from enum import Enum


class SomeEnum(Enum):
    A = 'A'
    B = 'B'
    C = 'C'


class EnumModel(QtCore.QAbstractListModel):

    def __init__(self, list_of_enums):
        """
        Enumeration model
        :param list_of_enums: list of enumeration values to show
        """
        QtCore.QAbstractListModel.__init__(self)
        self.items = list_of_enums

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.items)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid() is True:
            if role == QtCore.Qt.DisplayRole:
                return self.items[index.row()].value[0]
            elif role == QtCore.Qt.ItemDataRole:
                return self.items[index.row()].value[0]
            else:
                print('not recognised')
        return ""


if __name__ == '__main__':
    import sys

    model = EnumModel([SomeEnum.A, SomeEnum.A, SomeEnum.B, SomeEnum.C])

    app = QApplication(sys.argv)
    lst = QListView()
    lst.setModel(model)
    lst.show()
    sys.exit(app.exec_())

【问题讨论】:

  • list_of_enums 的值是多少,请提供minimal reproducible example。我已经通过将 QtCore.QVariant(self.items[index.row()].value[0]) 更改为 self.items[index.row()] 并通过 list_of_enums = ["a", "b", "c"] 测试了您的代码,并且它工作正常,所以我认为错误在 list_of_enums 中。
  • 如果您不打算显式返回值,则应改为调用基类data 方法。 role=13SizeHintRole,那么你返回的值是多少?
  • 嗨,我做了一个完整的例子。在 ubuntu 18.04、PySide2 5.12.3 下它没有在列表中显示任何内容。

标签: python pyqt5 pyside2


【解决方案1】:

问题在于,当视图需要与角色 Qt::SizeHintRole (13) 相关的信息时,您传递给它的是一个空字符串,而您必须返回 None 或者干脆不返回任何内容,因为它会干扰其他角色:

def data(self, index, role=QtCore.Qt.DisplayRole):
    if index.isValid():
        print(role)
        if role == QtCore.Qt.DisplayRole:
            return self.items[index.row()].value[0]
        elif role == QtCore.Qt.ItemDataRole:
            return self.items[index.row()].value[0]
        else:
            print('not recognised')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2013-03-21
    相关资源
    最近更新 更多