PySide 和 Qt 属性:将信号从 Python 连接到 QML

PySide and Qt Properties: Connecting signals from Python to QML

我正在尝试 运行 一个使用 QML 设计的简单 PySide 应用程序。我想在单独的线程中从 Python 调用 QML 中的函数。

我有以下 QML 视图:

import Qt 4.7

Rectangle {
    visible: true

    width: 100; height: 100
    color: "lightgrey"

    Text {
        id: dateStr
        objectName: "dateStr"
        x: 10
        y: 10
        text: "Init text"
        font.pixelSize: 12

        function updateData(text) {
            dateStr.text = qsTr(text)
            console.log("You said: " + text)
        }

    }

}

这是我的申请:

一些进口....

#!/usr/bin/python

import sys
import time

from PySide import QtDeclarative, QtCore 
from PySide.QtGui import QApplication
from PySide.QtDeclarative import QDeclarativeView

QThread 工作者....

#Worker thread
class Worker(QtCore.QThread):

    updateProgress = QtCore.Signal(int)

    def __init__(self, child):
        QtCore.QThread.__init__(self)
        self.child = child

    def run(self):
        while True:
            time.sleep(5)
            #Call the function updateData - DOES NOT WORK
            self.child.updateData("Other string ")

这里是组装的视图:

if __name__ == '__main__':

    # Create the Qt Application
    app = QApplication(sys.argv)
    # Create the view
    view = QDeclarativeView()
    # Connect it with QML
    view.setSource(QtCore.QUrl.fromLocalFile('main_ui.qml'))
    # Show UI
    view.show()

    #Get the root object and find the child dateStr
    root = view.rootObject()
    child = root.findChild(QtCore.QObject, "dateStr")

    #Call the function updateData - THIS WORKS
    child.updateData("String")

    worker = Worker(child)
    worker.start()

    sys.exit(app.exec_())

如果从 Qthread 调用 QML 函数 updateData(text),则不会设置 dateStr.text,但会生成控制台消息。如果从 main 函数中调用 QML 函数,dateStr.text 的更新工作正常。

问题

从 QtThread 调用 QML 函数的正确方法是什么?

链接

PySide tutorial: Connecting signals from Python to QML

我在其他帖子中找到了答案:

Whosebug: Pyside setText() not updating QLabel

在这种情况下,小部件不会重新绘制,因此需要强制应用程序重新绘制它。我使用了这段代码(参见 PySide Docs: QApplication):

def updateAllWidgets():
    for widget in QApplication.allWidgets():
        widget.update()

这个函数可以被定时器调用:

timer = QtCore.QTimer()
timer.start(1000)
timer.timeout.connect(updateAllWidgets)

另请参阅: PySide: Calling a Python function from QML and vice versa