从Qt Quick WorkerScrip调用Python方法

2024-05-03 18:29:01 发布

您现在位置:Python中文网/ 问答频道 /正文

如何从Qt QuickWorkerScript调用Python方法?在

前言:

通过注册QObject的子类,我成功地从QML应用程序访问Python方法:

class Foo(QtCore.QObject):
    @QtCore.pyqtSlot()
    def bar(self):
        pass # do stuff here

app = QtGui.QGuiApplication([])
QtQml.qmlRegisterType(Foo, 'Foo', 1, 0, 'Foo')
# more boilerplate Qt/Qt Quick

因此,在QML应用程序中,我可以成功地调用Foo.bar()。在

据我所知,我应该从WorkerScript调用任何长时间运行的函数。在

问题:

如何使用WorkerThread在后台线程中运行Foo.bar()?在

Per the docsWorkerScripts不能使用import语法,因此我不确定如果没有导入,我如何访问{}。在

更新:

我需要UI能够显示来自Foo.bar()的进度,因为该函数需要花费一点时间并做一些事情。在


Tags: 方法函数应用程序foodefbarqtqml
1条回答
网友
1楼 · 发布于 2024-05-03 18:29:01

^{}发送信息的唯一方法是通过^{}

sendMessage(jsobject message)

Sends the given message to a worker script handler in another thread. The other worker script handler can receive this message through the onMessage() handler.

The message object may only contain values of the following types:

  • boolean, number, string
  • JavaScript objects and arrays
  • ListModel objects (any other type of QObject* is not allowed)

All objects and arrays are copied to the message. With the exception of ListModel objects, any modifications by the other thread to an object passed in message will not be reflected in the original object.

但是,由于它读取所有元素都被复制(ListModel类型的元素除外),因此不可能使用从QObject类或其方法继承的任何对象。在


您可以将进程设置为pyqtProperty,这样您就可以将它公开给QML,并使用一个槽从另一个线程通过QRunnable更新它的值,更新是通过QMetaObject::invokeMethod()完成的

class Runnable(QRunnable):
    def __init__(self, obj):
        QRunnable.__init__(self)
        # main thread
        self.obj = obj

    def run(self):
        # another thread
        self.obj.bar()


class Foo(QObject):
    def __init__(self, *args, **kwags):
        QObject.__init__(self, *args, **kwags)
        self._progress = 0

    @pyqtSlot()
    def run_bar(self):
        self.runnable = Runnable(self)
        QThreadPool.globalInstance().start(self.runnable)

    progressChanged = pyqtSignal(int)

    @pyqtProperty(int, notify=progressChanged)
    def progress(self):
        return self._progress


    @pyqtSlot(int)
    def updateProgress(self, value):
        if self._progress == value:
            return
        self._progress = value
        self.progressChanged.emit(self._progress)

    def bar(self):
        for i in range(100):
            QMetaObject.invokeMethod(self, "updateProgress",
                                     Qt.QueuedConnection,
                                     Q_ARG(int, i))
            QThread.msleep(1000)

然后可以通过run_bar()启动它,并通过progress属性显示它:

^{pr2}$

完整的例子可以在下面的link

相关问题 更多 >