У меня есть определенный Python рабочий QObject
, который имеет медленный слот work()
, который вызывается интерфейсом QML (в моем реальном интерфейсе метод вызывается для каждого элемента в FolderListModel
динамически, как пользовательпроходит по списку, но для примера кода я просто вызываю его по завершении окна в качестве примера.
Я хотел бы запустить медленный work
асинхронно, чтобы предотвратить блокирование пользовательского интерфейса. Я думал сделать это, переместив экземпляр Worker в QThread и вызвав там слот, но это не работает, поскольку пользовательский интерфейс все еще заблокирован в ожидании результата work()
.
Этокод моей попытки до сих пор:
mcve.qml:
import QtQuick 2.13
import QtQuick.Window 2.13
Window {
id: window
visible: true
width: 800
height: 600
title: qsTr("Main Window")
Component.onCompleted: console.log(worker.work("I'm done!")) // not the actual usage, see note in the question
}
mcve.py:
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QUrl, QThread, QObject, Slot
from time import sleep
class Worker(QObject):
def __init__(self, parent=None):
super().__init__(parent)
@Slot(str, result=str)
def work(self, path):
sleep(5) # do something lengthy
return path
if __name__ == '__main__':
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
workerThread = QThread()
worker = Worker()
worker.moveToThread(workerThread)
engine.rootContext().setContextProperty("worker", worker)
engine.load(QUrl.fromLocalFile('mcve.qml'))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
Как мне вызвать work()
асинхронно, чтобытолько когда это сделано, его эффекты применяются? И, в качестве бонуса, что я делаю / неправильно понимаю при использовании QThreads?