With the below code, if you click start, a loop in qthread starts and when you click stop, it will terminate qthread by using ctypes. I know there are safer ways to terminiate qthread but since my actual code is way much longer than this, I think this method is better than other methods out there. The stop button works well for my intention but if I close gui, it will give me QThread: Destroyed while thread is still running. (even after the thread is terminated by using ctypes.pythonapi.PyThreadState_SetAsyncExc) I dont understand why I'm getting the error but I'm thinking ctypes.pythonapi.PyThreadState_SetAsyncExc doesnt actually terminate the thread but just pause the thread? I dont know.. It'd be very much appreciated if someone could tell me what I'm missing
import ctypes
import sys
import threading
import time
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.Button_state = True
self.pb_start.clicked.connect(self.click1_function)
# thread setup
self.test_thread_id = 0
def click1_function(self):
if self.Button_state:
self.Button_state = False
self.pb_start.setText('Stop')
self.test = Thread_Test1(self)
self.test.daemon = True
self.test.start()
elif self.Button_state == False:
self.Button_state = True
self.pb_start.setText('start')
self.test.stop_thread()
print('check')
def setupUi(self, QMainWindow):
self.resize(500, 500)
self.centralwidget = QtWidgets.QWidget(QMainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pb_start = QtWidgets.QPushButton(self.centralwidget)
self.pb_start.setGeometry(QtCore.QRect(100, 100, 100, 100))
self.pb_start.setObjectName("pb_start")
self.pb_start.setText("Start")
QMainWindow.setCentralWidget(self.centralwidget)
class Thread_Test1(QThread):
def __init__(self,parent):
super().__init__(parent)
self.parent = parent
def run(self):
i = 0
self.test_thread_id = int(self.currentThreadId())
while True:
print(i)
i += 1
time.sleep(1)
print("END")
print("End")
def stop_thread(self):
print (self.test_thread_id)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.test_thread_id,
ctypes.py_object(SystemExit))
if __name__ == "__main__":
app = QApplication(sys.argv)
myApp = MyWindow()
myApp.show()
app.exec_()