How can a python method/slot be connected to a QML signal? It looks like QtObject.connect() used to work in PyQt4 but it's no longer available in PyQt5.
#Sample QML File (stack.qml)
import QtQuick 2.0
Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
// relay this to python
}
}
}
--
#Sample Python File
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
if __name__ == '__main__':
import os
import sys
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setWidth(500)
view.setHeight(500)
view.setTitle('Hello PyQt')
view.setResizeMode(QQuickView.SizeRootObjectToView)
view.setSource(QUrl.fromLocalFile(os.path.join(os.path.dirname(__file__),'stack.qml')))
def on_qml_mouse_clicked(mouse_event):
print 'mouse clicked'
view.show()
qml_rectangle = view.rootObject()
# this technique doesn't work #############################
qml_rectangle.mousePressEvent.connect(on_qml_mouse_clicked)
sys.exit(app.exec_())
Some of the PyQT examples pass an object into the QML context via "setContextProperty" and then relay QML events to slots on that object but that approach seems roundabout. Is there a better way?
qml_rectangle.mousePressEvent
is not a signal, it's an event handler that is called on mouse events, so you can't connect to it. You could just replace it with your handler function (qml_rectangle.mousePressEvent = on_qml_mouse_clicked
), but that's not a very clean way of working with Qt.
The better way would be to define a signal in your qml file and emit it from the rectangle's onClicked
handler:
import QtQuick 2.0
Rectangle {
signal clicked()
MouseArea {
anchors.fill: parent
onClicked: {
parent.clicked() // emit the parent's signal
}
}
}
Then you can just connect to it from your python code:
...
def on_qml_mouse_clicked():
print('mouse clicked')
qml_rectangle.clicked.connect(on_qml_mouse_clicked)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With