Регистрация свойства списка Python в QML в pyside2

Я пытаюсь загрузить электронную таблицу и передать список рабочих листов обратно в свой интерфейс QML. Но я не могу найти способ вернуть список (а позже и словарь) в сценарий QML.

Вот мой QML:

FileDialog {
    id: openDialog
    title: "Open spreadsheet"
    nameFilters: [ "Excel files (*.xls *.xlsx)", "All files (*)" ]
    selectedNameFilter: "Excel files (*.xls *.xlsx)"
    onAccepted: {
        file.load(fileUrl)
        console.log(file.name)
        console.log(file.sheetnames)
    }
    onRejected: {
        console.log("Rejected")
    }
}

Вот мой класс Python:

class File(QtCore.QObject):

    def __init__(self, *args, **kwargs):
        super(File, self).__init__(*args, **kwargs)
        self.__filename = ""
        self.__sheetnames = list()

    @QtCore.Slot(str)
    def load(self, filename):
        self.__filename = re.sub(r'^[a-zA-Z]+:/+', '', filename)

        # Load the worksheet using openpyxl.
        try:
            workbook = openpyxl.load_workbook(filename=self.__filename)
        except openpyxl.utils.exceptions.InvalidFileException as exception:
            # Todo: write code to pass error to the user.
            print('Invalid File')
            return

        self.__sheetnames = workbook.sheetnames
        print(workbook.sheetnames)

    def set_filename(self):
        return self.__filename

    def get_filename(self, name):
        self.__filename = name

    def get_sheetnames(self):
        return self.__sheetnames

    def set_sheetnames(self, names):
        self.__sheetnames = names

    name = QtCore.Property(str, set_filename, get_filename)
    sheetnames = QtCore.Property(list, get_sheetnames, set_sheetnames)

Когда я открываю электронную таблицу, я получаю:

['Sheet1']
qml: C:/path/to/my/spreadsheet.xlsx
qml: QVariant(PySide::PyObjectWrapper)

Первая строка показывает, что у python есть правильный список, во второй мой скрипт в QML успешно получает строковое свойство, но третья не получает должным образом свойство списка.


person MVanOrder    schedule 21.02.2018    source источник
comment
Может быть, это глупый вопрос, но я вижу, что он печатает имена файлов и файлов, но я не вижу, в какое время он загрузил какое-либо значение в файл.   -  person eyllanesc    schedule 21.02.2018
comment
Функция file.load () загружает файл, открытый с помощью FileDialog, с помощью openpyxl.load_workbook (), затем устанавливает его защищенные переменные __filename и __sheetnames, к которым имеют доступ свойства.   -  person MVanOrder    schedule 21.02.2018
comment
мой вопрос ориентирован на то, чтобы спросить, где вы используете file.load ()?   -  person eyllanesc    schedule 21.02.2018
comment
Удаляя отключенные строки из своего сообщения, я удалил слишком много. Я повторно добавил его в блок кода QML.   -  person MVanOrder    schedule 21.02.2018


Ответы (1)


Вы должны использовать QVariantList вместо списка, кроме того, использование регулярных выражений может привести к сбою, в моем случае я использую Linux и создаю проблемы, поэтому правильнее всего использовать QUrl:

class File(QtCore.QObject):
    filenameChanged = QtCore.Signal()
    sheetnamesChanged = QtCore.Signal()

    def __init__(self, *args, **kwargs):
        super(File, self).__init__(*args, **kwargs)
        self.__filename = ""
        self.__sheetnames = list()

    @QtCore.Slot(str)
    def load(self, filename):
        self.__filename = QtCore.QUrl(filename).toLocalFile()
        # Load the worksheet using openpyxl.
        try:
            workbook = openpyxl.load_workbook(filename=self.__filename)
        except openpyxl.utils.exceptions.InvalidFileException as exception:
            # Todo: write code to pass error to the user.
            print('Invalid File')
            return

        self.__sheetnames = workbook.sheetnames
        print(workbook.sheetnames)

    @QtCore.Property(str, notify=filenameChanged)
    def filename(self):
        return self.__filename

    @filename.setter
    def get_filename(self, name):
        if name == self.__filename:
            return
        self.__filename = name
        self.filenameChanged.emit()

    @QtCore.Property('QVariantList', notify=sheetnamesChanged)
    def sheetnames(self):
        return self.__sheetnames

    @sheetnames.setter
    def set_sheetnames(self, names):
        if names == self.__sheetnames:
            return
        self.__sheetnames = names[:]
        self.sheetnamesChanged.emit()

Вывод:

['Periodic Table']
qml: /home/eyllanesc/Downloads/Ultimate Periodic Table1.xlsx
qml: [Periodic Table]
person eyllanesc    schedule 21.02.2018