Альтернатива QVariant при миграции с PyQt5 на PySide2 - PullRequest
2 голосов
/ 13 мая 2019

У меня возникли проблемы с переключением с 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.

В своих усилиях по миграции я обнаружил, что официальный сайт сообщает:

PySide поддерживает только API 2 PyQt (см. PSEP 101) для получения подробной информации.Поэтому классы Qt, такие как QStrings, QStringLists и QVariants, недоступны в 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_())

1 Ответ

1 голос
/ 14 мая 2019

Проблема в том, что когда представлению требуется информация, относящаяся к роли 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')
...