I am fairly new to Qt/PyQt and currently struggling with some basic functionality. What I'm trying to do is, to dynamically load QML-Views (*.qml) files from python and replace specific content on the fly. For example a checkbox gets checked and part of my current view is replaced with another qml file. First I wanted to provide this logic via PyQt, but it seems a StackView is a better idea (multiple qml files in pyqt).
However, in this case I am not able to inject properties into my QML files. I am only able to inject a property into the rootContext. That however limits the usage of my QML-Views since I can only use one view (of the same type) at once. I would like to inject properties dynamically into QML-Views and make them only visible to this particular view. In this case I can use the same view more than once with more than one object in the back-end to catch the signals.
Here is my SimpleMainWindow.qml file (the main view:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
objectName : "WINDOW"
property ApplicationWindow appWindow : window
}
And here the file I try to load (TestViewButton.qml):
import QtQuick 2.9
import QtQuick.Controls 1.4
Button {
id: test
text: "test"
objectName : "Button"
onClicked: {
configurator.sum(1, 2)
configurator.info("TestOutput")
}
}
Python file loading QML-View (Component)
from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine, QQmlComponent
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load("qml/SimpleMainWindow.qml")
engine.quit.connect(app.quit)
rootWindow = engine.rootObjects()[0].children()[0].parent()
# create component
component = QQmlComponent(engine)
component.loadUrl(QUrl("qml/TestViewButton.qml"))
configurator = SignalHandler()
component.setProperty("configurator", configurator)
itm = component.create()
itm.setParentItem(rootWindow.children()[0])
itm.setProperty("configurator", configurator)
app.exec_()
And the python object that I use to handle the signals from the view (SignalHandler.py):
from PyQt5.QtCore import QObject, pyqtSlot
class SignalHandler(QObject):
@pyqtSlot(int, int)
def sum(self, arg1, arg2):
print("Adding two numbers")
@pyqtSlot(str)
def info(self, arg1):
print("STR " + arg1)
The button loads fine (by the way, is there a better way to identify the parent I want to add my button to, wasn't having any look with findChild). What is not working is the component.setProperty.... part. If I set the property in the rootContext of the engine it works fine (the SignalHandler methods are called). Already checked similar topics (like Load a qml component from another qml file dynamically and access that component's qml type properties ...)
Is this possible, or am I getting something wrong here?
thanks