Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么input()会导致;QCoreApplication::exec:事件循环已在运行;?_Python_Multithreading_Input_Pyqt4_Qcoreapplication - Fatal编程技术网

Python 为什么input()会导致;QCoreApplication::exec:事件循环已在运行;?

Python 为什么input()会导致;QCoreApplication::exec:事件循环已在运行;?,python,multithreading,input,pyqt4,qcoreapplication,Python,Multithreading,Input,Pyqt4,Qcoreapplication,我遇到了这个QCoreApplication问题,在QObject在QThread内完成执行后调用input()会导致无限循环打印到控制台“QCoreApplication::exec:事件循环已在运行” 在代码中,我创建了一个作为QObject的泛型worker,将其移动到一个QThread(使用QThread的认可方式,而不是子类化),然后在泛型worker内执行另一个QObject的(主类)函数。只要在主控执行后不调用input(),一切都正常。请注意,如果直接在worker中执行函数(而

我遇到了这个QCoreApplication问题,在QObject在QThread内完成执行后调用input()会导致无限循环打印到控制台“QCoreApplication::exec:事件循环已在运行”

在代码中,我创建了一个作为QObject的泛型worker,将其移动到一个QThread(使用QThread的认可方式,而不是子类化),然后在泛型worker内执行另一个QObject的(主类)函数。只要在主控执行后不调用input(),一切都正常。请注意,如果直接在worker中执行函数(而不是主实例的函数),也会出现问题

下面是重现问题的示例代码:

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()

在您的示例中,
输入
没有真正的问题。在
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()
,您将看到这三个行都在主线程中执行。这是因为您连接了
线程。在将辅助线程移动到另一个线程之前启动
信号。解决此问题的最佳(即最容易维护的)方法是始终在跨线程连接的任何插槽上使用
@pyqtSlot
装饰器,因为这样一来,在进行信号连接时就无关紧要了。(有关此问题的更完整解释,请参阅)。

在您的示例中,
输入没有实际问题。在
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()
,您将看到这三个行都在主线程中执行。这是因为您连接了
线程。在将辅助线程移动到另一个线程之前启动
信号。解决此问题的最佳(即最容易维护的)方法是始终在跨线程连接的任何插槽上使用
@pyqtSlot
装饰器,因为这样一来,在进行信号连接时就无关紧要了。(有关此问题的更完整解释,请参阅)。

太棒了!我用你的答案解决了两个问题。非常感谢,太好了!我用你的答案解决了两个问题。谢谢。