카테고리 없음
[pyside2] QThread 올바르게 종료하기
mistive
2020. 7. 22. 13:09
import sys
import time
from PySide2.QtCore import * # Signal()
from PySide2.QtGui import *
from PySide2.QtWidgets import * # QMainWindow, QWidget, QGridLayout
#qthread 에러 없이 종료하기
class UserButton(QPushButton):
def __init__(self):
super(UserButton, self).__init__()
self._prop = 'false'
with open('test3.css', encoding='utf-8') as f:
self.setStyleSheet(f.read())
def getter(self):
return self._prop
def setter(self, val):
if self._prop == val:
return
self._prop = val
self.style().polish(self)
prop = Property(str, fget=getter, fset=setter)
class intervalThread(QThread):
def __init__(self, b1:UserButton, b2:UserButton):
super(intervalThread,self).__init__()
self.working = True
self.b1 = b1
self.b2 = b2
def run(self):
while self.working:
if self.b1.prop == 'true':
self.b1.prop = 'false'
else:
self.b1.prop = 'true'
print(self.b1.prop)
self.sleep(1)
def stop(self):
self.working = False
self.quit()
self.wait(5000) #5000ms = 5s
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
# QWidget.__init__(self)
self.layout = QGridLayout()
self.setLayout(self.layout)
self.button1 = UserButton()
self.button2 = UserButton()
self.layout.addWidget(self.button1, 0, 0, 1, 1)
self.layout.addWidget(self.button2, 0, 1, 1, 1)
self.thread = intervalThread(self.button1, self.button2)
self.thread.start()
def closeEvent(self, e):
self.hide()
self.thread.stop()
def keyReleaseEvent(self, e):
if e.key() == Qt.Key_Escape:
self.close()
if e.key() == Qt.Key_S:
self.thread.working=True
self.thread.start()
print("S")
if e.key() == Qt.Key_P:
self.thread.working=False
print("P")
app = QApplication(sys.argv)
lf = MainWindow()
lf.show()
sys.exit(app.exec_())
Thread가 종료되기 전에 main Loop가 종료될 경우 에러코드를 리턴하며 프로그램이 종료된다.
이를 해결하기 위해 mainLoop가 종료되기 전에 Thread를 종료시키고 Thread 종료가 완료될 때까지 대기시키면 된다.
MainWindow의 closeEvent와 thread class 내의 사용자함수인 stop() 안에 있는 quit(), wait()기능을 이용해서 말이다.
대신 문제가 wait()의 deadline을 설정해주지 않으면 제대로 동작을 하지 않는 경우가 발생한다.
그래서 나는 5000ms(=5s)로 deadline을 설정해놓았다.
이렇게 하면 thread가 종료되기 전에 closeEvent 발생으로 인해 mainLoop가 종료되지 않아 에러코드 없이 0을 리턴하면서 프로그램이 종료하게 된다.