반응형
PySide6에서 안전하게 스레드 멈추기
PySide6에서 UI를 멈추지 않고 백그라운드 작업을 수행하려면 QThread를 활용해야 합니다. 하지만 한 번 실행된 스레드를 안전하게 멈추는 방법을 모른다면 프로그램이 멈추거나 오류가 발생할 수 있습니다. 이 글에서는 QThread를 활용하여 스레드를 실행하고, 안전하게 정지 명령을 전달하여 스레드를 중단하는 방법을 설명합니다.
1. 스레드란?
🔍 스레드 개념 쉽게 이해하기
컴퓨터 프로그램은 기본적으로 한 가지 작업을 순차적으로 처리합니다. 하지만, 프로그램이 하나의 작업만 처리한다면 시간이 오래 걸리는 연산이 있을 경우 UI가 멈추거나 응답하지 않는 현상이 발생할 수 있습니다.
이를 해결하기 위해 멀티스레딩(Multithreading) 을 사용하면 여러 개의 작업을 동시에 실행할 수 있습니다. 스레드는 하나의 프로그램 내에서 독립적으로 실행되는 작은 단위의 작업을 의미합니다.
🖥️ 스레드의 실생활 예시
- 유튜브 동영상 시청: 동영상을 재생하는 동안 UI는 버튼 클릭을 계속 받을 수 있음.
- 파일 다운로드: 백그라운드에서 다운로드가 진행되면서 동시에 다른 작업을 수행할 수 있음.
- 채팅 프로그램: 메시지를 보내고 받는 동안 UI가 멈추지 않음.
⚠️ 스레드 사용 시 주의할 점
- 여러 개의 스레드가 동시에 실행되면 충돌이 발생할 수 있음.
- UI 업데이트는 반드시 메인 스레드에서 실행해야 함.
- 스레드를 안전하게 종료하지 않으면 프로그램이 비정상적으로 동작할 수 있음.
2. 필요한 사항
PySide6에서 스레드를 활용하려면 아래 사항을 확인하세요.
📌 필요한 모듈
- PySide6.QtCore 모듈: QThread, Signal, Slot 사용
- PySide6.QtWidgets 모듈: UI 구성에 필요한 QApplication, QPushButton, QVBoxLayout, QWidget 사용
⚠️ 스레드 관련 주의점
- UI 업데이트는 반드시 메인 스레드에서 실행해야 합니다.
- QThread의 terminate() 메서드는 사용하지 않는 것이 좋습니다. 강제 종료는 예상치 못한 오류를 유발할 수 있기 때문입니다.
- QThread의 isRunning()을 활용하여 스레드 상태를 체크할 수 있습니다.
반응형
3. 예제 코드
다음 예제에서는 WorkerThread 클래스를 생성하여 백그라운드 작업을 실행하고, 버튼을 눌러 스레드를 멈출 수 있도록 구현합니다.
✏️ 코드 설명
- WorkerThread 클래스는 QThread를 상속받아 실행됩니다.
- run() 메서드에서 루프를 실행하면서 작업을 수행합니다.
- stop() 메서드를 만들어 안전하게 루프를 종료하도록 설정합니다.
- UI에서 버튼을 눌러 스레드를 시작하고 중지할 수 있도록 연결합니다.
import sys
import time
from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
class WorkerThread(QThread):
progress = Signal(int) # 진행 상태를 전달하는 시그널
def __init__(self):
super().__init__()
self._is_running = True # 스레드 실행 상태 플래그
def run(self):
count = 0
while self._is_running:
count += 1
self.progress.emit(count) # 진행 상태 시그널 전송
time.sleep(1) # 1초 대기
def stop(self):
self._is_running = False # 스레드 종료 플래그 설정
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QThread 정지 예제")
self.setGeometry(100, 100, 300, 200)
self.button_start = QPushButton("스레드 시작", self)
self.button_stop = QPushButton("스레드 정지", self)
self.button_start.clicked.connect(self.start_thread)
self.button_stop.clicked.connect(self.stop_thread)
layout = QVBoxLayout()
layout.addWidget(self.button_start)
layout.addWidget(self.button_stop)
self.setLayout(layout)
self.thread = WorkerThread()
self.thread.progress.connect(self.update_status)
def start_thread(self):
if not self.thread.isRunning():
self.thread = WorkerThread()
self.thread.progress.connect(self.update_status)
self.thread.start()
def stop_thread(self):
self.thread.stop()
self.thread.wait() # 스레드가 완전히 종료될 때까지 대기
def update_status(self, count):
print(f"진행 상태: {count}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
4. 테이블 정리
항목 | 설명 |
QThread | PySide6에서 스레드를 실행하는 클래스 |
run() | 스레드 실행 시 호출되는 메서드 (여기에 반복 작업 작성) |
stop() | 스레드 종료 플래그를 변경하는 메서드 |
progress | 작업 진행 상태를 시그널로 전달 |
isRunning() | 스레드가 실행 중인지 확인하는 메서드 |
wait() | 스레드 종료를 대기하는 메서드 |
반응형
'코딩취미 > Python' 카테고리의 다른 글
파이썬에서 멀티태스킹과 멀티스레드 사용법 (0) | 2025.02.28 |
---|---|
파이썬에서 안전하게 멀티스레드 생성 및 관리하기(QThreadPool, QRunnable) (0) | 2025.02.28 |
PyInstaller 패키징 시 "모듈을 찾을 수 없음" 오류 해결 방법 (0) | 2025.02.27 |
PySide6로 파일 이동 및 압축하기 – ZIP, TAR, 7Z 압축을 활용한 GUI 프로그램 제작 (0) | 2025.02.27 |
[파이썬, pyside6] MD5 해시란? MD5 해시를 생성하고 비교하는 방법 (0) | 2025.02.27 |