목적: 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함수를 실행하게 됨.
출처
- https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing