PySide6 Signal - QtQuick Slot Using QQmlApplicationEngine.setInitialProperties()
In the previous example we’ve had a PySide6 signal, a Qml slot, and the connection is made in PySide6. In this one we still have a PySide6 signal and a Qml slot but we connect them in the Qml file. To do this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ApplicationWindow {
id: mainWindow
visible: true
width: 400
height:200
title: "Template App"
// 1. Add a property named timer to the root object
property variant timer
RowLayout {
anchors.fill: parent
Label {
id: label
text: "Hello Qml!"
Layout.fillWidth: true
Layout.fillHeight: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize:24
font.bold: true
color: "steelblue"
// 3. Use the Qml Connections type to connect
// QTimer.timeout to the Qml slot
// Target is the slot owner (ie QTimer)
// and the slot name, onTimeout matches
// the signal name, timeout
Connections {
target: mainWindow.timer
function onTimeout () {
label.text =
Qt.formatTime(new Date, "hh:mm:ss")
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import sys
from PySide6.QtCore import QObject, QTimer
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.quit.connect(app.quit)
# 2. Create a timer and set the root object
# timer property value to it.
timer = QTimer()
timer.start(1000)
# it appears that you need to set properties
# before loading the Qml file.
engine.setInitialProperties({'timer': timer})
engine.load('02_setinitialproperties.qml')
root = engine.rootObjects()[0]
label = root.findChild(QObject, 'label')
result = app.exec()
del engine
sys.exit(result)
-
Add a custom property to the Qml ApplicationWindow. Custom properties can be of any of the Qml value types like
bool
,int
orstring
but asQTimer
is an object we set the property type tovariant
(althoughvar
would also work). -
In the PySide6 file, create a
QTimer
object namedtimer
and useQQmalApplicationEngine.setInitialProperties()
to assigntimer
to theApplicationWindow.timer
property we created in 1.setInitialProperties()
accepts a Python dictionary and in this case it has only one element. You need tosetInitialProperties()
before youload()
the Qml file or the Qml engine will complain:Unable to assign [undefined] to QObject*
. -
Back in Qml, use the
Connections
type to create the slot and connect the signal with it.Connections.target
holds a reference to the object that emits the signal and the slot and the signal names need to match: the signal’s name istimeout
so the slot needs to be namedonTimeout
. The slot sets the label’s text to the current time just as in the first example.