Qthread工作仍然在关闭GUI时进行中的Python PyQ

2024-06-16 09:34:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码有线程,但是当我关闭gui时,它仍然在后台工作。如何停止线程?有没有什么东西stop(),close()? 我不用信号,插槽?我必须用这个吗?在

from PyQt4 import QtGui, QtCore
import sys
import time
import threading

class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.kac_ders=QtGui.QComboBox()
        self.bilgi_cek=QtGui.QPushButton("Save")
        self.text=QtGui.QLineEdit()
        self.widgetlayout=QtGui.QFormLayout()
        self.widgetlar=QtGui.QWidget()
        self.widgetlar.setLayout(self.widgetlayout)
        self.bilgiler=QtGui.QTextBrowser()
        self.bilgi_cek.clicked.connect(self.on_testLoop)
        self.scrollArea = QtGui.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setWidget(self.widgetlar)
        self.analayout=QtGui.QVBoxLayout()
        self.analayout.addWidget(self.text)
        self.analayout.addWidget(self.bilgi_cek)
        self.analayout.addWidget(self.bilgiler)
        self.centralWidget=QtGui.QWidget()
        self.centralWidget.setLayout(self.analayout)
        self.setCentralWidget(self.centralWidget)

    def on_testLoop(self):
        self.c_thread=threading.Thread(target=self.kontenjan_ara)
        self.c_thread.start()

    def kontenjan_ara(self):

        while(1):
                self.bilgiler.append(self.text.text())
                time.sleep(10)


app = QtGui.QApplication(sys.argv)
myWidget = Main()
myWidget.show()
app.exec_()

Tags: textimportselfmaindef线程qtguicek
2条回答

我选择重写这个答案,因为我没有正确地看待问题的背景。正如其他答案和注释所说,您的代码缺乏线程安全性。在

解决这个问题的最好方法是试着真正地“在线程中”思考,限制自己只使用生活在同一线程中的对象,或者被称为“线程安全”的函数。在

加入一些信号和插槽会有所帮助,但也许你想回想一下你最初的问题。在当前代码中,每按一个按钮,就会启动一个新线程,该线程每10秒执行两个操作: -阅读self.text中的一些文本 -将其附加到self.bilgiler

这两个操作都是非线程安全的,必须从拥有这些对象的线程(主线程)调用。您希望让工作线程“调度并等待”read&append操作,而不是简单地“执行”它们。在

我建议使用另一个答案(线程停止问题是通过使用与Qt的事件循环很好地集成的适当的qthread自动修复的),这将使您使用更干净的方法,与Qt更集成。在

您可能还需要重新考虑您的问题,因为可能有一种更简单的方法来解决您的问题,例如:不在每次单击bilgi_cek时生成线程,或者使用Queue对象,这样您的工作人员就完全不知道您的GUI,并且只使用线程安全对象与它交互。在

祝你好运,如果我给你带来什么麻烦,对不起。我原来的答案仍然有效here。我认为把另一个答案作为这个问题的有效答案是明智的。在

几件事:

  1. 你不应该在主线程之外调用GUI代码。GUI元素不是线程安全的。self.kontenjan_ara更新和读取GUI元素,它不应该是您的thread的目标。

  2. 在几乎所有情况下,您应该使用QThreads而不是python线程。它们与Qt中的事件和信号系统很好地集成在一起。

如果您只想每隔几秒钟运行一次,可以使用QTimer

^{1}$

如果线程操作在计算上更复杂,可以创建一个工作线程,并使用信号在工作线程和主GUI线程之间传递数据。在

^{pr2}$

当主线程退出事件循环时,Qt将自动终止所有子线程。在

相关问题 更多 >