QThread

Qtμ—μ„œ μŠ€λ ˆλ“œλ₯Ό κ΄€λ¦¬ν•˜λŠ” κΈ°λ³Έ 클래슀

  • QThread λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œμš΄ μŠ€λ ˆλ“œλ₯Ό 생성, μ‹€ν–‰ κ°€λŠ₯

κΈ°λ³Έ κ°œλ…

  • QThread λŠ” 독립적인 μ‹€ν–‰ 흐름을 κ°–λŠ” λ³„λ„μ˜ μŠ€λ ˆλ“œλ₯Ό 생성
  • μŠ€λ ˆλ“œκ°€ μ‹œμž‘λ˜λ©΄ λ‚΄λΆ€μ μœΌλ‘œ run() λ©”μ†Œλ“œ 호좜
    • μ‚¬μš©μžλŠ” run() λ©”μ†Œλ“œλ₯Ό 직접 ν˜ΈμΆœν•˜μ§€ μ•Šκ³ , start() λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μŠ€λ ˆλ“œ μ‹œμž‘
  • QThreadλŠ” 자체 이벀트 루프 exec() λ₯Ό 보유, Signal-Slot 톡신, 타이머 λ“± 이벀트 처리 κ°€λŠ₯
  • μŠ€λ ˆλ“œκ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆ 메인 μŠ€λ ˆλ“œ (GUI)λŠ” 응닡 μƒνƒœλ₯Ό μœ μ§€ β†’ ν”„λ‘œκ·Έλž¨μ΄ λ©ˆμΆ”λŠ” ν˜„μƒ λ°©μ§€

μ£Όμš” λ©”μ„œλ“œ

κ΅¬ν˜„

​1. run() λ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ“œ

import sys
 
from PySide6.QtCore import QThread, Signal, Slot
from PySide6.QtWidgets import (
	QApplication, QMainWindow, QWidget,
	QVBoxLayout, 
	QPushButton, QLabel
)
 
 
class WorkerThread(QThread):
	result_ready = Signal(str)    ## μž‘μ—…μ΄ μ™„λ£Œλ˜μ—ˆμŒμ„ λ‚˜νƒ€λ‚΄λŠ” μ‹œκ·Έλ„
	
	def run(self) -> None:
		for i in range(5):
			self.sleep(1)
			self.result_ready.emit(f"Count: {i + 1}")
 
 
class MainWindow(QMainWindow):
	def __init__(self) -> None :
		super().__init__()
		
		self.thread = WorkerThread()
		
		self._setup_ui()
		self._setup_connections()
	
	def _setup_ui(self) -> None :
		## μ°½ μ„€μ •
		self.setWindowTitle("QThread Example")
		
		container = QWidget()
		self.setCentralWidget(container)
		
		layout = QVBoxLayout(self)
		container.setLayout(layout)
		
		## UI μ„€μ •
		self.label = QLabel("")
		self.start_button = QPushButton("Start", self)
		
		layout.addWidget(self.label)
		layout.addWidget(self.start_button)
	
	def _setup_connections(self) -> None :
		self.thread.result_ready.connect(self.update_text)
		self.start_button.clicked.connect(self.start_thread)
	
	@Slot(str)
	def update_text(self, text) -> None :
		self.label.setText(text)
	
	def start_thread(self) -> None :
		self.thread.start()
 
 
if __name__ == '__main__' :
	app = QApplication(sys.argv)
	
	window = MainWindow()
	window.show()
	
	app.exec()
 
  • QThread λ₯Ό μƒμ†λ°›λŠ” WorkerThread 클래슀λ₯Ό 생성, λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μˆ˜ν–‰
  • μŠ€λ ˆλ“œμ—μ„œ μž‘μ—…μ΄ μ™„λ£Œλ  λ•Œ λ§ˆλ‹€ result_ready μ‹œκ·Έλ„μ„ 방좜
  • 메인 μœˆλ„μš°λŠ” 이 μ‹œκ·Έλ„μ„ μˆ˜μ‹ , ν…μŠ€νŠΈ μ—…λ°μ΄νŠΈ
전체 μ½”λ“œ
import sys
 
from PySide6.QtCore import QThread, Signal, Slot
from PySide6.QtWidgets import (
	QApplication, QMainWindow, QWidget,
	QVBoxLayout, 
	QPushButton, QLabel
)
 
 
class WorkerThread(QThread):
	result_ready = Signal(str)    ## μž‘μ—…μ΄ μ™„λ£Œλ˜μ—ˆμŒμ„ λ‚˜νƒ€λ‚΄λŠ” μ‹œκ·Έλ„
	
	def run(self) -> None:
		for i in range(5):
			self.sleep(1)
			self.result_ready.emit(f"Count: {i + 1}")
 
 
class MainWindow(QMainWindow):
	def __init__(self) -> None :
		super().__init__()
		
		self.thread = WorkerThread()
		
		self._setup_ui()
		self._setup_connections()
	
	def _setup_ui(self) -> None :
		## μ°½ μ„€μ •
		self.setWindowTitle("QThread Example")
		
		container = QWidget()
		self.setCentralWidget(container)
		
		layout = QVBoxLayout(self)
		container.setLayout(layout)
		
		## UI μ„€μ •
		self.label = QLabel("")
		self.start_button = QPushButton("Start", self)
		
		layout.addWidget(self.label)
		layout.addWidget(self.start_button)
	
	def _setup_connections(self) -> None :
		self.thread.result_ready.connect(self.update_text)
		self.start_button.clicked.connect(self.start_thread)
	
	@Slot(str)
	def update_text(self, text) -> None :
		self.label.setText(text)
	
	def start_thread(self) -> None :
		self.thread.start()
 
 
if __name__ == '__main__' :
	app = QApplication(sys.argv)
	
	window = MainWindow()
	window.show()
	
	app.exec()

2. moveToThread() μ‚¬μš©


Reference

PySide6 Threading κ΄€λ ¨ κΈ€