PyQt5 QML Signal to Python Slot?
python方法/插槽如何连接到QML信号? 看起来QtObject.connect()曾经在PyQt4中工作,但在PyQt5中不再可用。
1 2 3 4 5 6 7 8 9 10 11 12 | #Sample QML File (stack.qml) import QtQuick 2.0 Rectangle { MouseArea { anchors.fill: parent onClicked: { // relay this to python } } } |
-
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 | #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_()) |
一些PyQT示例通过" setContextProperty"将对象传递到QML上下文中,然后将QML事件中继到该对象上的插槽,但是这种方法似乎是round回的。 有没有更好的办法?
更好的方法是在qml文件中定义一个信号,并从矩形的
1 2 3 4 5 6 7 8 9 10 11 | import QtQuick 2.0 Rectangle { signal clicked() MouseArea { anchors.fill: parent onClicked: { parent.clicked() // emit the parent's signal } } } |
然后,您可以从python代码连接到它:
1 2 3 4 5 6 | ... def on_qml_mouse_clicked(): print('mouse clicked') qml_rectangle.clicked.connect(on_qml_mouse_clicked) ... |
我建议子类化QQuickView并在其根上下文中设置属性,例如MainWindow。现在,您需要做的就是在类中添加带有@pyqtSlot('QString')之类装饰的函数,然后可以使用onClicked设置事件处理程序:MainWindow.FunctionName(Arguments_According_To_Decoration)
然后您的main.py看起来像这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/env python3 # -*- coding: utf-8 -*- from PyQt5.QtCore import pyqtSlot from PyQt5.QtCore import QUrl from PyQt5.QtQuick import QQuickView from PyQt5.QtWidgets import QApplication import sys class MainWindow(QQuickView): def __init__(self): super().__init__() self.setSource(QUrl('sample.qml')) self.rootContext().setContextProperty("MainWindow", self) self.show() @pyqtSlot('QString') def Print(self, value): print(value) if __name__ == '__main__': app = QApplication(sys.argv) w = MainWindow() sys.exit(app.exec_()) |
和sample.qml一样
1 2 3 4 5 6 7 8 9 10 11 | import QtQuick 2.0 import QtQuick.Controls 2.2 Rectangle { width: 200; height: 200 Button { text:"print Hello World" onClicked: MainWindow.Print('hello world') } } |
您可以在文档中找到更多信息
http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html