Есть ли способ получить содержимое ListModel из QML в pyqt? - PullRequest
1 голос
/ 15 апреля 2020

В моем TableView у меня есть ListModel, который заполняется пользователем. Я хочу сохранить эту модель в виде файла .csv, используя python. Но я не могу отправить модель через сигнал qml в pyqt (нет типа для моделей), и если я хочу получить доступ к этому ListModel в python, используя эту строку.

Python

model = self.engine.rootObjects()[0].findChild(QObject, "newCsvModel")

В ответ я получаю QAbstractListModel, который (в моем понимании) не содержит содержимого модели.

QML

Вот как я использую свою модель

TableView {
            model: ListModel{
                id: csvModel
                objectName: "newCsvModel"

                ListElement{
                    key1: "val1"
                    key2: "val2"
                    ...
                }
                ...
            }

У меня есть класс для отправки точного типа модели из pyqt в qml, и он работает нормально, но сделать это наоборот - проблематично c для меня. Знаете ли вы, как извлечь данные из qml ListModel?

1 Ответ

0 голосов
/ 16 апреля 2020

Не следует экспортировать напрямую в объект QML, вместо этого используйте объект QObject, который выбирает объект QML через слот для получения модели, получая доступ к ролям и значениям, чтобы сохранить его в .csv.

import csv

from PyQt5 import QtCore, QtGui, QtQml


class CSVHelper(QtCore.QObject):
    @QtCore.pyqtSlot("QAbstractItemModel*", str)
    def saveListModel(self, model, filename):
        headers = {v.data().decode(): k for k, v in model.roleNames().items()}
        with open(filename, mode="w") as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=headers.keys())
            writer.writeheader()

            for i in range(model.rowCount()):
                row = dict()
                for name, role in headers.items():
                    value = model.index(i, 0).data(role)
                    row[name] = value
                writer.writerow(row)


if __name__ == "__main__":
    import os
    import sys

    app = QtGui.QGuiApplication(sys.argv)

    csv_helper = CSVHelper()

    engine = QtQml.QQmlApplicationEngine()
    engine.rootContext().setContextProperty("CSVHelper", csv_helper)
    file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(file))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

main.qml

import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4


ApplicationWindow {
    id: root
    visible: true
    width: 640
    height: 480

    ListModel {
        id: libraryModel
        ListElement {
            title: "A Masterpiece"
            author: "Gabriel"
        }
        ListElement {
            title: "Brilliance"
            author: "Jens"
        }
        ListElement {
            title: "Outstanding"
            author: "Frederik"
        }
    }
    Column{
        Button {
            text: "Press me"
            onClicked: CSVHelper.saveListModel(libraryModel, "data.csv")
        }
        TableView {
            width: root.width
            height: 400
            TableViewColumn {
                role: "title"
                title: "Title"
                width: 100
            }
            TableViewColumn {
                role: "author"
                title: "Author"
                width: 200
            }
            model: libraryModel
        }
    }
}
...