[英]Pyqt5 Multi-threading Error: QObject::connect: Cannot queue arguments of type 'QTextCursor'
[英]Easy Multi-threading with PyQt5, for updating QTextBrowser contents
我在網上發現了一些東西,表明PyQt5小部件不是線程安全的。 其他Stackoverflow答案建議創建一個僅適合其問題的類。 我嘗試在Python 3中使用_thread
模塊,該模塊適用於除PyQt之外的所有內容。
app = QApplication([])
Ui_MainWindow, QtBaseClass = uic.loadUiType("UI/action_tab.ui") #specify the location of your .ui file
class MyApp(QMainWindow):
def __init__(self):
super(MyApp, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.threadPool = QThreadPool()
self.ui.queryBox.returnPressed.connect(self.load_response)
def start_loader(self):
self.loading_animate = QMovie('IMAGES/GIFS/load_resp.gif')
self.loading_animate.setScaledSize(QSize(400, 300))
self.ui.loader.setMovie(self.loading_animate)
self.loading_animate.setSpeed(200)
self.ui.loader.show()
self.loading_animate.start()
def stop_loader(self):
self.ui.loader.hide()
self.loading_animate.stop()
def get_response(self):
plain_text, speech = get_Wresponse(self.ui.queryBox.displayText())
self.stop_loader()
self.ui.textDisplay.setText(plain_text)
if speech == '':
say("Here you GO!")
else:
say(speech)
def load_response(self):
self.start_loader()
_thread.start_new_thread(self.get_response, ())
#self.get_response()
if __name__ == '__main__':
window = MyApp()
window.setWindowFlags(Qt.FramelessWindowHint)
window.show()
sys.exit(app.exec())
上面代碼中的錯誤如下,
QObject: Cannot create children for a parent that is in a different thread. (Parent is QTextDocument(0x19fe090b8c0), parent's thread is QThread(0x19fde197fb0), current thread is QThread(0x19fe3a0a5f0)
你認為你可以救我嗎? 請做! 提前致謝!!
您不必從外部線程更新GUI。 QMetaObject::invokeMethod(...)
有信號, QMetaObject::invokeMethod(...)
,QEvent和QTimer::singleShot(0, ...)
幾種選項。
使用最后一種方法,解決方案如下:
from functools import partial
from PyQt5.QtCore import pyqtSlot
class MyApp(QMainWindow):
# ...
@pyqtSlot()
def stop_loader(self):
self.ui.loader.hide()
self.loading_animate.stop()
def get_response(self, text):
plain_text, speech = get_Wresponse(text)
QtCore.QTimer.singleShot(0, self.stop_loader)
wrapper = partial(self.ui.textDisplay.setText, plain_text)
QtCore.QTimer.singleShot(0, wrapper)
if speech == '':
say("Here you GO!")
else:
say(speech)
def load_response(self):
self.start_loader()
text = self.ui.queryBox.displayText()
_thread.start_new_thread(self.get_response, (text,))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.