Tony Stark Tony Stark - 2 months ago 10
Python Question

Qthread is still working when i close gui on python pyqt

my code has thread, but when i close the gui, it still works on background. how can i stop threads? is there something stop(), close()?
i dont use signal, slots? Must i use this?

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

Answer

I chose to rewrite a bit this answer, because I had failed to properly look at the problem's context. As the other answers and comments tell, you code lacks thread-safety.

The best way to fix this is to try to really think "in threads", to restrict yourself to only use objects living in the same thread, or functions that are known as "threadsafe".

Throwing in some signals and slots will help, but maybe you want to think back a bit to your original problem. In your current code, each time a button is pressed, a new thread in launched, that will, every 10 seconds, do 2 things : - Read some text from self.text - Append it to self.bilgiler

Both of these operations are non-threadsafe, and must be called from the thread that owns these objects (the main thread). You want to make the worker threads "schedule & wait" the read & append oeprations, instead of simply "executing" them.

I recommend using the other answer (the thread halting problem is automatically fixed by using proper QThreads that integrate well with Qt's event loop), which would make you use a cleaner approach, more integrated with Qt.

You may also want to rethink your problem, because maybe there is a simpler approach to your problem, for example : not spawning threads each time bilgi_cek is clicked, or using Queue objects so that your worker is completely agnostic of your GUI, and only interact with it using threadsafe objects.

Good luck, sorry if I caused any confusion. My original answer is still available here. I think it would be wise to mark the other answer as the valid answer for this question.

Comments