동시성과 병렬성
import threading
import time
class BackgroundWorker(threading.Thread): # 스레드를 상속받은 백그라운드 작업 클래스
# 생성자
def __init__(self, names: str) -> None:
super().__init__()
self.name = f'{threading.current_thread().name} : {names}'
def run(self) -> None:
print(f'BackgroundWorker start : {self._name}')
# time.sleep(2)
print(f'BackgroundWorker end : {self._name}')
if __name__ == '__main__':
print('메인 스레드 시작') # 기본 프로세스 == 메인 스레드
for i in range(5):
name = f'서브 스레드 {i}'
th = BackgroundWorker(name)
th.start() # run 이 실행 됨
print('메인 스레드 종료')
Qt Designer
python 코드
# 스레드 미사용 앱
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * # QIcon 여기있음
from PyQt5.QtCore import * # Qt.white 여기 있음
class qtApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi('./studyThread/threadApp.ui',self)
self.setWindowTitle('노스레드 앱 v0.4')
self.pgbTask.setValue(0)
self.btnStart.clicked.connect(self.btnStartClicked)
def btnStartClicked(self):
self.pgbTask.setRange(0,100)
for i in range(0,101): # 0~100까지 범위
print(f'노스레드 출력 > {i}')
self.pgbTask.setValue(i)
self.txbLog.append(f'노스레드 출력 > {i}')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = qtApp()
ex.show()
sys.exit(app.exec_())
스레드 시작 누르면
스레드를 안 쓰면 프로세스가 충돌이 일어나기 때문에 스레드를 써야한다!
스레드 사용하는 앱
# 스레드 사용 앱
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * # QIcon 여기있음
from PyQt5.QtCore import * # Qt.white 여기 있음
import time
class BackgroundWorker(QThread): # pyqt5 스레드를 위한 클래스 존재
procChanged = pyqtSignal(int)
def __init__(self, count = 0, parent = None) -> None:
super().__init__()
self.main = parent
self.working = False # 스레드 동작여부
self.count = count
def run(self):
# self.parent.pgbTask.setRange(0,100)
# for i in range(0,101):
# print(f'스레드 출력 > {i}')
# self.parent.pgbTask.setValue(i)
# self.parent.txbLog.append(f'스레드 출력 > {i}')
while self.working:
self.procChanged.emit(self.count) # 시그널을 내보냄
self.count += 1 # 값 증가만
time.sleep(0.0001)
class qtApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi('./studyThread/threadApp.ui',self)
self.setWindowTitle('스레드 앱 v0.5')
self.pgbTask.setValue(0)
self.btnStart.clicked.connect(self.btnStartClicked)
# 스레드 초기화
self.worker = BackgroundWorker(parent=self,count=0)
# 백그라운드 워커에 있는 시그널을 접근 슬롯함수
self.worker.procChanged.connect(self.procUpdated)
self.pgbTask.setRange(0,1000000)
@pyqtSlot(int)
def procUpdated(self, count):
self.txbLog.append(f'스레드 출력 > {count}')
self.pgbTask.setValue(count)
print(f'스레드 출력 > {count}')
def btnStartClicked(self):
self.worker.start()
self.worker.working = True
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = qtApp()
ex.show()
sys.exit(app.exec_())
문제없이 잘 작동한다.
BUT 100%가 되어도 계속 진행됨
# 스레드 사용 앱
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * # QIcon 여기있음
from PyQt5.QtCore import * # Qt.white 여기 있음
import time
MAX = 10000
class BackgroundWorker(QThread): # pyqt5 스레드를 위한 클래스 존재
procChanged = pyqtSignal(int) # 커스텀 시그널
def __init__(self, count = 0, parent = None) -> None:
super().__init__()
self.main = parent
self.working = False # 스레드 동작여부
self.count = count
def run(self): # thread.start() --> run() 대신 실행
while self.working:
if self.count <= MAX:
self.procChanged.emit(self.count) # 시그널을 내보냄(emit)
self.count += 1 # 값 증가만
time.sleep(0.0001) # 0.0000001 처럼 세밀하게 하면 GUI처리를 제대로 못 함
else:
self.working = False # 멈춤
class qtApp(QWidget): # 전체동작
def __init__(self):
super().__init__()
uic.loadUi('./studyThread/threadApp.ui',self)
self.setWindowTitle('스레드 앱 v0.5')
self.pgbTask.setValue(0)
self.btnStart.clicked.connect(self.btnStartClicked)
# 스레드 생성
self.worker = BackgroundWorker(parent=self,count=0)
# 백그라운드 워커에 있는 시그널을 접근 슬롯함수
self.worker.procChanged.connect(self.procUpdated)
self.pgbTask.setRange(0,MAX)
# @pyqtSlot(int) : 데코레ㅔ이션
def procUpdated(self, count):
self.txbLog.append(f'스레드 출력 > {count}')
self.pgbTask.setValue(count)
print(f'스레드 출력 > {count}')
def btnStartClicked(self):
self.worker.start() # 스레드 클래스 run()실행
self.worker.working = True
self.worker.count = 0
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = qtApp()
ex.show()
sys.exit(app.exec_())