PyQt5 QML信号到Python插槽?

ber*_*erg 8 qt pyqt qml pyqt5

如何将python方法/槽连接到QML信号?看起来QtObject.connect()曾经在PyQt4中工作,但它在PyQt5中不再可用.

#Sample QML File (stack.qml)

import QtQuick 2.0

Rectangle {
    MouseArea {
        anchors.fill: parent
        onClicked: {
           // relay this to python
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

-

#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_())
Run Code Online (Sandbox Code Playgroud)

一些PyQT示例通过"setContextProperty"将对象传递到QML上下文,然后将QML事件中继到该对象上的插槽,但这种方法似乎是迂回的.有没有更好的办法?

mat*_*ata 15

qml_rectangle.mousePressEvent它不是一个信号,它是一个在鼠标事件上调用的事件处理程序,因此您无法连接它.你可以用你的处理函数(qml_rectangle.mousePressEvent = on_qml_mouse_clicked)替换它,但这不是一个非常干净的Qt工作方式.

更好的方法是在qml文件中定义一个信号并从矩形的onClicked处理程序中发出它:

import QtQuick 2.0

Rectangle {
    signal clicked()
    MouseArea {
        anchors.fill: parent
        onClicked: {
           parent.clicked()  // emit the parent's signal
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以从你的python代码连接到它:

...
def on_qml_mouse_clicked():
    print('mouse clicked')

qml_rectangle.clicked.connect(on_qml_mouse_clicked)
...
Run Code Online (Sandbox Code Playgroud)