The only method to send information to the WorkerScript is through sendMessage():
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.
But since it reads all the elements are copied (except those of type ListModel), so it is not possible to use any object that inherits from the QObject class or its methods.
You can make the progress a pyqtProperty so you can expose it to QML, and use a slot to update its values from another thread through QRunnable with QThreadPool, the update is done through 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)
Then you can start it through run_bar (), and show it through the progress property:
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
}
}
}
}
The complete example can be found in the following link