从PyQt5迁移到PySide2时的QVariant替代方案

时间:2019-05-13 18:30:23

标签: python pyqt5 pyside2

由于以下代码,我在从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)以获取详细信息。   因此,Qt类(例如QStrings,QStringLists和QVariants)是   在PySide上不可用。相反,您应该只使用本机Python   数据类型。

因此,解决方案是(我想)将QVariant更改为str。当我这样做时,该类不会引发任何错误,但也不会显示该模型。

实际上,函数data正在接收role=13而不是role=QtCore.Qt.DisplayRole

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

一个最小的可行示例是:

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

1 个答案:

答案 0 :(得分: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')