我的代码有线程,但是当我关闭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_()
我选择重写这个答案,因为我没有正确地看待问题的背景。正如其他答案和注释所说,您的代码缺乏线程安全性。在
解决这个问题的最好方法是试着真正地“在线程中”思考,限制自己只使用生活在同一线程中的对象,或者被称为“线程安全”的函数。在
加入一些信号和插槽会有所帮助,但也许你想回想一下你最初的问题。在当前代码中,每按一个按钮,就会启动一个新线程,该线程每10秒执行两个操作: -阅读
self.text
中的一些文本 -将其附加到self.bilgiler
这两个操作都是非线程安全的,必须从拥有这些对象的线程(主线程)调用。您希望让工作线程“调度并等待”read&append操作,而不是简单地“执行”它们。在
我建议使用另一个答案(线程停止问题是通过使用与Qt的事件循环很好地集成的适当的qthread自动修复的),这将使您使用更干净的方法,与Qt更集成。在
您可能还需要重新考虑您的问题,因为可能有一种更简单的方法来解决您的问题,例如:不在每次单击
bilgi_cek
时生成线程,或者使用Queue
对象,这样您的工作人员就完全不知道您的GUI,并且只使用线程安全对象与它交互。在祝你好运,如果我给你带来什么麻烦,对不起。我原来的答案仍然有效here。我认为把另一个答案作为这个问题的有效答案是明智的。在
几件事:
你不应该在主线程之外调用GUI代码。GUI元素不是线程安全的。
self.kontenjan_ara
更新和读取GUI元素,它不应该是您的thread
的目标。在几乎所有情况下,您应该使用
QThreads
而不是python线程。它们与Qt中的事件和信号系统很好地集成在一起。如果您只想每隔几秒钟运行一次,可以使用
^{1}$QTimer
如果线程操作在计算上更复杂,可以创建一个工作线程,并使用信号在工作线程和主GUI线程之间传递数据。在
^{pr2}$当主线程退出事件循环时,Qt将自动终止所有子线程。在
相关问题 更多 >
编程相关推荐