如何在Qt Quick中将按钮绑定到Python(PyQt)?

7 投票
2 回答
12256 浏览
提问于 2025-04-18 09:04

我想点击一个用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')
      }
     }
    }

2 个回答

3

还有另一种解决方案,它在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")
    }
}

参考资料:

  1. https://wiki.qt.io/Qt_for_Python/Connecting_QML_Signals
3

如果你给按钮起个名字,就可以把它的点击信号连接起来,或者连接它在 onClicked 中发出的自定义信号。举个例子:

ApplicationWindow {
 title: qsTr("Test Invoke")
 width: 200
 height: 100

 Button {
  signal messageRequired
  objectName: "myButton"
  y : 70
  text : "About"
  onClicked: messageRequired()

 }
}

注意按钮中的信号和对象名称属性。然后在 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 的槽函数都会被调用。

撰写回答