Я в основном следую инструкциям здесь для использования свойств, и я мог бы просто использовать данный объект Person в качестве внутреннего, но это не очень полезно. Я пытаюсь понять, как сделать следующие две вещи:
- Использовать несколько экземпляров нескольких таких классов в бэкэнде и соединить их так, чтобы PySide / QML не жаловался
- Разрешить настройку серверной части модулями во время выполнения (т. Е. Я в конечном итоге хочу компонентизировать приложение - иметь разные компоненты, реализующие интерфейс, компонент вносит свой вклад как в GUI, так и в серверную часть; но этот вопрос касается только бэкэнд)
Это в отличие от простого определения всех этих свойств вместе с их установщиком и геттером в основном бэкэнд-классе (что я смог сделать), что я имею в виду под modularize в вопросе.
Я изменяю пример Person по ссылке, чтобы сделать его чем-то, что пользовательский интерфейс может изменить, и присвоил ему дополнительный атрибут для ударов ...
person.py
from PySide2.QtCore import QObject, Signal, Property
class Person(QObject):
def __init__(self, name, age):
QObject.__init__(self)
self._name = name
self._age = age
def getName(self):
return self._name
def setName(self, name):
print(f"Setting name to {name}")
self._name = name
def getAge(self):
return self._age
def setAge(self, age):
print(f"Setting age to {age}")
self._age = age
@Signal
def name_changed(self):
pass
@Signal
def age_changed(self):
pass
name = Property(str, getName, setName, notify=name_changed)
age = Property(str, getAge, setAge, notify=age_changed)
В качестве примера я создам два экземпляра Person. Первый экземпляр, который я создал как член класса. Это не совсем то, что я хочу, но ближе напоминает способ, которым свойства использовались в ссылке. Второй экземпляр - это то, что я действительно хочу, это то, что свойства являются членами экземпляра, так что я могу добавить их из другого места приложения во время выполнения. Ни один из методов в настоящее время не работает
main.py
import sys
from os.path import abspath, dirname, join
from PySide2.QtCore import QObject, Property, Signal
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from person import Person
class Backend(QObject):
def __init__(self):
QObject.__init__(self)
def registerProperty(self, name : str, prop):
setattr(self, name, prop)
person1 = Person("Jill", 29)
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
context = engine.rootContext()
# Instance of the Python object
backend = Backend()
# simulate properties added by another module
backend.registerProperty("person2", Person("Jack", 30))
qmlFile = join(dirname(__file__), 'view3.qml')
engine.load(abspath(qmlFile))
# Expose the Python object to QML
context.setContextProperty("backend", backend)
# I tried this but it did nothing
# context.setContextProperty("backend.jack", backend.jack)
# context.setContextProperty("backend.jill", backend.jill)
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
наконец, файл view3.qml просто
import QtQuick 2.0
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
ApplicationWindow {
visible: true
ColumnLayout {
TextField {
implicitWidth: 200
onAccepted: {
backend.person1.name = text
}
}
TextField {
implicitWidth: 200
onAccepted: {
backend.person1.age = text
}
}
TextField {
implicitWidth: 200
onAccepted: {
backend.person2.name = text
}
}
TextField {
implicitWidth: 200
onAccepted: {
backend.person2.age = text
}
}
}
}
Когда я пытаюсь установить любое из значений в пользовательском интерфейсе, ошибка всегда одинакова (ошибка появляется в файле QML)
TypeError: Value is undefined and could not be converted to an object
В конечном счете, я хотел бы, чтобы такие объекты были вложены на любую произвольную глубину , Есть ли способ достичь того, что я пытаюсь сделать здесь? Или я, возможно, совершенно не в курсе того, как я об этом говорю?