我想单击 QML 中制作的按钮并执行在我的 Python (PyQt) 代码中定义的函数。我该怎么做?
main.py:
import sys
from PyQt5.QtCore import QObject, QUrl, Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("main", engine)
engine.load('test.qml')
win = engine.rootObjects()[0]
win.show()
sys.exit(app.exec())
main.qml:
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.1
ApplicationWindow {
title: qsTr("Test Invoke")
width: 200
height: 100
Button{
y : 70
text : "About"
onClicked: {
print('Hello')
}
}
}
如果为按钮命名,则可以连接到其 onClick 信号,或连接到它在
onClicked
中发出的自定义信号。示例:
ApplicationWindow {
title: qsTr("Test Invoke")
width: 200
height: 100
Button {
signal messageRequired
objectName: "myButton"
y : 70
text : "About"
onClicked: messageRequired()
}
}
注意 Button 中的信号和 objectName 属性。那么
exec
之前的 Python 代码可以是:
def myFunction():
print 'handler called'
button = win.findChild(QObject, "myButton")
button.messageRequired.connect(myFunction)
button.clicked.connect(myFunction) # works too
请注意,在上面的按钮中,
onClicked
仅发出messageRequired
信号,因此最好放弃自定义信号并直接连接到clicked
。当您单击按钮时,onClicked()
以及连接到 clicked
的任何插槽都会被调用。
还有另一种解决方案,它在 QML 中使用 Python 模型(QObject)。
Python
engine = QQmlApplicationEngine()
engine.load("main.qml")
class Greeter(QObject):
@pyqtSlot(str)
def sayHello(self, name):
print("Hello, " + name)
ctx = engine.rootContext()
ctx.setContextProperty("greeter", Greeter())
QML
Button {
onClicked: {
greeter.sayHello("Alice")
}
}
参考。