I want to keep order in my project, hence I thought about moving the properties from the "main.py" file to another called "CustomVariables.py". But now I get "TypeError: Cannot read property 'loaderSource' of undefined". When you uncomment the comments in the code below, it works OK, however I don't want to declare properties inside "BG" class. Can anyone guide me how to properly set this up?
CustomVariables.py
from PySide6.QtCore import QObject, Property, Signal
class CustomVariables(QObject):
def __init__(self):
QObject.__init__(self)
self.loaderSource = 'PageWork.qml'
def get_loaderSource(self):
return self._loaderSource
def set_loaderSource(self, new_loaderSource):
self._loaderSource = new_loaderSource
self.loaderSourceChanged.emit()
loaderSourceChanged = Signal()
loaderSource = Property(str, get_loaderSource, set_loaderSource, notify=loaderSourceChanged)
main.py
import sys
from pathlib import Path
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QObject, Property, Signal
from CustomVariables import CustomVariables
class BG(QObject):
def __init__(self):
QObject.__init__(self)
# self.loaderSource = 'PageWork.qml'
cv = CustomVariables()
# def get_loaderSource(self):
# return self._loaderSource
# def set_loaderSource(self, new_loaderSource):
# self._loaderSource = new_loaderSource
# self.loaderSourceChanged.emit()
# loaderSourceChanged = Signal()
# loaderSource = Property(str, get_loaderSource, set_loaderSource, notify=loaderSourceChanged)
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
background = BG()
engine.rootContext().setContextProperty("bg", background)
qml_file = Path(__file__).resolve().parent / "main.qml"
engine.load(qml_file)
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
main.qml
import QtQuick.Controls.FluentWinUI3
import QtQuick
Window {
id: root
width: 1280
height: 720
visible: true
Loader {
id: projectLoader
anchors.fill: parent
asynchronous: true
source: bg.cv.loaderSource
//source: bg.loaderSource
}
}
I tried also to declare the "cv" inside "init":
self.cv = CustomVariables()
but still without success
QML doesn't know about dependency relationships between objects unless you set them with QProperties. Python class relationships don't come into play in QML since it doesn't have introspection of those objects. In your case cv has to be a constant QProperty, meaning that the reference to the cv object does not change.
Another mistake of yours is that _loaderSource is not initialized so it will return an error.
class CustomVariables(QObject):
def __init__(self):
QObject.__init__(self)
self._loaderSource = "PageWork.qml"
def get_loaderSource(self):
return self._loaderSource
def set_loaderSource(self, new_loaderSource):
self._loaderSource = new_loaderSource
self.loaderSourceChanged.emit()
loaderSourceChanged = Signal()
loaderSource = Property(
str, get_loaderSource, set_loaderSource, notify=loaderSourceChanged
)
class BG(QObject):
def __init__(self):
QObject.__init__(self)
self._cv = CustomVariables()
@Property(QObject, constant=True)
def cv(self):
return self._cv