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을 리턴하면서 프로그램이 종료하게 된다.

+ Recent posts