본문 바로가기

프로그래밍/PyQt5 GUI

58. 타이머와 스레드

58-1 예제1: ex57

import sys
import threading
from PyQt5.QtWidgets import QApplication, QWidget, QPlainTextEdit, QScrollBar
from PyQt5.QtCore import Qt, QTimer

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.timer = QTimer(self)
        self.timer.start(1000)
        self.timer.timeout.connect(self.time_slot)

        self.plainText = QPlainTextEdit(self)
        self.plainText.move(10, 10)
        self.plainText.resize(280, 180)
        self.plainText.addScrollBarWidget(QScrollBar(Qt.Vertical), Qt.AlignRight)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle("Timer&Thread")
        self.show()

    def time_slot(self):
        name = threading.currentThread().getName()
        self.plainText.appendPlainText(f"timer slot is called by {name}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MyApp()
    sys.exit(app.exec_())

58-2 설명

실행 프로그램은 하나 이상의 스레드를 갖는데 이를 Main Thread라고 합니다. 위의 코드와 같이 타이머 객체를 만든 후 1초에 한 번씩 timeout 이벤트가 발생하도록 하면 1초에 한 번 콜백되는 메서드인 time_slot은 메인 스레드에서 처리됩니다.

58-3 결과

58-4 예제2

import sys
import threading
import time

from PyQt5.QtWidgets import QApplication, QWidget, QPlainTextEdit, QScrollBar
from PyQt5.QtCore import Qt, QTimer

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.timer = QTimer(self)
        self.timer.start(1000)
        self.timer.timeout.connect(self.time_slot)

        self.plainText = QPlainTextEdit(self)
        self.plainText.move(10, 10)
        self.plainText.resize(280, 180)
        self.plainText.addScrollBarWidget(QScrollBar(Qt.Vertical), Qt.AlignRight)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle("Timer&Thread")
        self.show()

    def time_slot(self):
        name = threading.currentThread().getName()
        self.plainText.appendPlainText(f"timer slot is called by {name}")
        self.plainText.appendPlainText("before sleep")
        time.sleep(5)
        self.plainText.appendPlainText("after sleep")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MyApp()
    sys.exit(app.exec_())

58-5 설명

타이머의 timeout 이벤트 역시 메인 스레드가 처리하므로 시간이 오래 걸리는 작업을 타이머 슬롯 내에서 처리하면 전체 이벤트 루프가 멈추게 됩니다.

즉 5초 동안  '닫기' 를 마우스로 클릭해도 이벤트가 전혀 먹지 않는 먹통 현상이 발생합니다.

 

58-6 결과

'프로그래밍 > PyQt5 GUI' 카테고리의 다른 글

60. 멀티스레딩  (0) 2021.08.10
59. 이벤트 루프  (0) 2021.08.10
57. 타이머  (0) 2021.08.09
35. QPlainTextEdit  (0) 2021.08.09
56. 텍스트 그리고 (drawText)  (0) 2021.07.30