【发布时间】: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=13是SizeHintRole,那么你返回的值是多少? -
嗨,我做了一个完整的例子。在 ubuntu 18.04、PySide2 5.12.3 下它没有在列表中显示任何内容。