![](/img/trans.png)
[英]Solution for : QCoreApplication::exec: The event loop is already running [closed]
[英]Why does input() cause “QCoreApplication::exec: The event loop is already running”?
我遇到了這個QCoreApplication問題,其中在QObject在QThread中執行完后調用input()會導致無限循環打印到控制台“ QCoreApplication :: exec:事件循環已在運行”。
在代碼中,我創建了一個通用工作器作為QObject,將其移動到QThread(批准使用的方法來使用QThread,而不是對其進行子類化),然后在通用工作器內執行另一個QObject的(Master類)函數。 只要在執行完Master之后我不調用input(),一切都會正常。 請注意,如果我直接在worker中執行一個函數(而不是Master實例的函數),也會發生此問題。
這是重現該問題的示例代碼:
import sys
from PyQt4.QtCore import QCoreApplication, QObject, QThread, pyqtSignal, pyqtSlot
class Worker(QObject):
"""
Generic worker.
"""
start = pyqtSignal(str)
finished = pyqtSignal()
def __init__(self, function):
QObject.__init__(self)
self._function = function
self.start.connect(self.run)
def run(self):
self._function()
self.finished.emit()
class Master(QObject):
"""
An object that will use the worker class.
"""
finished = pyqtSignal()
def __init__(self):
QObject.__init__(self)
@pyqtSlot()
def do(self):
print("Do what?")
self.finished.emit()
def done():
# FIXME This will cause an infinite loop printing to the console:
# "QCoreApplication::exec: The event loop is already running"
input("Enter your answer: ")
def main():
app = QCoreApplication(sys.argv)
master = Master()
worker = Worker(master.do)
master.finished.connect(done)
thread = QThread()
thread.started.connect(worker.run)
worker.moveToThread(thread)
# Terminating thread gracefully, or so.
worker.finished.connect(thread.quit)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
thread.start()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
您的示例中的input
沒有真正的問題。 在done()
按下enter鍵后,控制將返回到事件循環,然后等待進一步的用戶交互-這是正常且預期的行為。
您沒有明確說明此后會發生什么。 但是,如果要退出程序,請執行以下操作:
def done():
input("Enter your answer: ")
QCoreApplication.quit()
Qt警告消息是無害的,但是可以這樣刪除:
def main():
from PyQt4.QtCore import pyqtRemoveInputHook
pyqtRemoveInputHook()
app = QCoreApplication(sys.argv)
...
您的示例中唯一真正的問題是線程實現。 如果將print(QThread.currentThread())
行添加到Worker.run()
, Master.do()
和main()
,您將看到這三個都在主線程中執行。 這是因為您在將工作進程移動到另一個線程之前連接了thread.start
信號。 解決此問題的最佳方法(即最容易維護的方法)是始終在跨線程連接的任何插槽上使用@pyqtSlot
裝飾器-因為那樣建立信號連接時就沒有關系了。 (有關此問題的更完整說明,請參見此答案 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.