[Python] GUI와 Multi-Threading 사용 (GUI + Multi-Threading)

목적: GUI (tkinter)와 Multi-Threading (threading) 사용

환경: Linux (Ubuntu 16.04)

Python Version: 3.5.2

import queue #MK: queue를 사용하기 위해 추가
import threading #MK: threading을 사용하기 위해 추가
import time #MK: time을 사용하기 위해 추가
import tkinter #MK: tkinter(GUI)를 사용하기 위해 추가

class mainThread:
	def __init__(self):
		self.tk = tkinter.Tk();

	def beginThread(self): 
		self.queue = queue.Queue(); #MK: queue를 생성함.
		threadTask(self.queue).start(); #MK: 생성된 queue를 threadTask에 전달함.다른 thread에서 threadTask 연산을 시작함. 
		self.tk.after(100, self.processQueue) #MK: 100 milliseconds 후에 self.processQueue 함수를 실행함
			
	def processQueue(self):
		try:
			msg = self.queue.get(0); #MK: threadTask가 보내는 메시지를 받음 
			print(msg);
		except queue.Empty: #MK: 만약 message가 없으면 expect를 통하여 해당 함수 연산을 다시 수행함
			self.tk.after(100, self.processQueue);
	
class threadTask(threading.Thread):
	def __init__(self, queue):
		threading.Thread.__init__(self); #MK:새로운 thread를 생성하는 단계로 판단됨. threadTask가 기존 threading.Thread class를 override하는 것으로 판단됨.
		self.queue = queue; #MK: mainThread에서 보낸 queue를 threadTask class의 queue와 연결함
	def run(self): #MK: 기존 threading class의 run함수 override함
		time.sleep(5) #MK: 5초 동안 thread가 아무 일을 하지 않음
		self.queue.put("Task Finished") #MK: 해당 메시지를 queue에 추가함
	
tmp = mainThread();
tmp.beginThread();
tmp.tk.mainloop();

추가 설명

  • GUI와 Threading을 동시에 사용해야 하는 이유는 tkinter (GUI)를 효율적으로 사용하기 위해서이다. 보통 GUI의 버튼을 클릭하면 특정 함수의 연산을 수행하게 된다. 만약 해당 함수를 실행하는 데 오랜 시간이 걸리면 tkinter은 함수의 결과가 return 되지 않기 때문에 멈추는 현상이 발생한다. 그동안 GUI에 어떠한 부분도 사용할 수 없다. 이 문제를 해결하기 위해서 Multi-Threading을 활용하여 오랜 시간이 걸리는 연산을 다른 Thread에서 실행하게 된다. GUI 연산을 수행하는 Thread는 오랜 시간이 필요한 연산을 수행하지 않기 때문에 계속 GUI를 업데이트 할 수 있다.

설명

  • beginThread() 함수에서 Queue()를 생성함. 생성된 Queue는 threadTask Class의 __init__함수로 보냄. 해당 Queue는 mainThread thread와 threadTask thread와의 통신을 하기 위한 수단이 됨.
  • beginThread()함수 안에 threadTask(queue).start()는 threadTask Class의 run함수를 실행하게 됨.
  • tk.after(milliseconds, 실행함수명)을 사용하여 특정 시간 후에 실행할 함수명을 선택함. 본 예제에서는 100 milliseconds 후에 processQueue함수를 실행하게 됨.

출처

  1. https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing

Leave a Comment