python - 从 Windows cmd 或 IDLE 而不是 PyCharm 运行时出现 "QThread: Destroyed while thread is still running"?

标签 python multithreading pyqt freeze destroy

这是使用QObject.moveToThread 实现PyQt 多线程程序的简化版本。基本上,我在单独的线程上查询网页并提取 HMTL 内容。

我在从 IDLE 运行代码或 Windows 命令行挂起 python 时遇到这个问题。 Windows cmd 显示“QThread:线程仍在运行时已被销毁”。但是,如果我从 Pycharm 运行它,一切正常。

您可以获得.ui 文件here

有什么想法吗?

import requests
import sys
from PyQt4 import QtGui, uic
from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QThread


qtCreatorFile = "window.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)


class HttpClient(QObject):

    finished =  pyqtSignal(str)

    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot()
    def retrieve_page(self, url):
        response = requests.get(url)
        self.finished.emit(response.text)


class HtmlGetter(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)       
        self.go_button.clicked.connect(self.query_page)

    def query_page(self):
        http_client = HttpClient()
        temp_thread = QThread()
        http_client.moveToThread(temp_thread)

        temp_thread.started.connect(
        lambda: http_client.retrieve_page("http://www.google.com/"))
        http_client.finished.connect(self.show_html)

        # Terminating thread gracefully.
        http_client.finished.connect(temp_thread.quit)
        http_client.finished.connect(http_client.deleteLater)
        temp_thread.finished.connect(temp_thread.deleteLater)

        temp_thread.start()

    def show_html(self, html_text):
        print(html_text)


def main():
    app = QtGui.QApplication(sys.argv)
    window = HtmlGetter()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

最佳答案

我想通了:

http_client 和temp_thread 都必须是属性或HtmlGetter 类。我认为这是因为否则 python 在退出函数时会丢弃它们。这是工作代码:

import requests
import sys
from PyQt4 import QtGui, uic
from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QThread


qtCreatorFile = "window.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)


class HttpClient(QObject):

    finished =  pyqtSignal()
    send_text = pyqtSignal(str)

    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot()
    def retrieve_page(self, url):
        response = requests.get(url)
        self.send_text.emit(response.text)
        self.finished.emit()


class HtmlGetter(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)       
        self.go_button.clicked.connect(self.query_page)

    def query_page(self):
        self.http_client = HttpClient()
        self.temp_thread = QThread()
        self.http_client.moveToThread(self.temp_thread)

        self.temp_thread.started.connect(
        lambda: self.http_client.retrieve_page("http://www.google.com/"))
        self.http_client.send_text.connect(self.show_html)

        # Terminating thread gracefully.
        self.http_client.finished.connect(self.temp_thread.quit)
        self.http_client.finished.connect(self.http_client.deleteLater)
        self.temp_thread.finished.connect(self.temp_thread.deleteLater)

        self.temp_thread.start()

    def show_html(self, html_text):
        print(html_text)


def main():
    app = QtGui.QApplication(sys.argv)
    window = HtmlGetter()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

关于python - 从 Windows cmd 或 IDLE 而不是 PyCharm 运行时出现 "QThread: Destroyed while thread is still running"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38829023/

相关文章:

python - 根据结构化数组python中的条件生成随机值

python - Matplotlib 和检查按钮定制

c# - 当我尝试在 if() 中使用变量时,它说我正在使用未分配的变量

python - 如何在 PyQt 应用程序退出时禁用清除剪贴板?

debugging - 如何在我的 QWebView 小部件中嵌入 Firebug Lite?

python - 如何使用 pip 在 Windows 上安装 PyQt4?

python - 在迭代数据帧时将 pandas 数据帧中的特定行写入 csv 文件

python - 使用numpy将两个数组垂直合并为元组数组

c++ - 我们什么时候使用 QMutexLocker 重新锁定和解锁?

java - 如何在所有子线程执行完毕后运行主线程