从Qt Quick WorkerScript调用Python方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Qt Quick WorkerScript调用Python方法相关的知识,希望对你有一定的参考价值。
如何从Qt Quick WorkerScript
调用Python方法?
Preamble:
我已经设法通过注册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
调用任何长期运行的函数。
Problem:
如何使用Foo.bar()
在后台线程中运行WorkerThread
?
Per the docs,WorkerScript
s不能使用import
语法,所以我不确定如何在没有导入的情况下访问Foo
。
Update:
我需要UI能够显示来自Foo.bar()
的进度,因为该功能需要一些时间并做几件事。
向WorkerScript
发送信息的唯一方法是通过sendMessage()
:
sendMessage(jsobject消息)
将给定消息发送到另一个线程中的工作者脚本处理程序。另一个worker脚本处理程序可以通过onMessage()处理程序接收此消息。
消息对象可能只包含以下类型的值:
- 布尔值,数字,字符串
- JavaScript对象和数组
- ListModel对象(不允许任何其他类型的QObject *)
所有对象和数组都将复制到消息中。除ListModel对象外,其他线程对传入消息的对象的任何修改都不会反映在原始对象中。
但由于它读取了所有复制的元素(ListModel类型除外),因此不可能使用任何继承自QObject类或其方法的对象。
您可以将进度设为pyqtProperty
,以便将其暴露给QML
,并使用插槽通过QRunnable
通过QThreadPool
从另一个线程更新其值,更新通过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属性显示它:
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.0
import QtQuick 2.0
import Foo 1.0
ApplicationWindow{
width: 300
height: 300
visible: true
Text{
id:txt
text: "press me to start"
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Foo{
id: foo
onProgressChanged: txt.text= progress
}
MouseArea {
anchors.fill: parent
onClicked: foo.run_bar()
}
statusBar: StatusBar {
RowLayout {
anchors.fill: parent
ProgressBar {
value: foo.progress
maximumValue: 100
anchors.fill: parent
}
}
}
}
完整的示例可以在以下link中找到
以上是关于从Qt Quick WorkerScript调用Python方法的主要内容,如果未能解决你的问题,请参考以下文章