백그라운드 작업하기 II (쓰레드)
간단한 백그라운드 작업은 Idle 핸들러
나, 타이머 핸들러
를 이용하여 작업이 가능하나, 복잡하고 처리량이 많은 작업의 경우에는 쓰레드를 이용하는 것이 훨씬 효율적이므로, 여기에서는 쓰레드 작업 시 GUI 컨트롤을 업데이트해야 하는 방법에 대해서 알아본다.
기본적으로 사용자 쓰레드에서는 GUI를 업데이트할 수 없다. 따라서 쓰레드 작업중 GUI 업데이트가 필요한 경우에는, 다음과 같이 wx.CallAfter()
함수를 이용하여 메인 쓰레드에서 처리하도록 해야 한다.
참고
ew.callAfter() 함수는 wx.CallAfter() 함수와 동일한 wrapper 함수 이다.
def threadGuiAction(status_text):
def action():
appWin.setStatusText(status_text)
return action
def threadWorker(args):
global runcount
while True:
ew.callAfter(threadGuiAction(args + ": " + str(runcount)))
runcount += 1
time.sleep(0.1)
if __name__ == "__main__":
appWin = ew.WxApp(u"Thread Demo", 320, 240)
appWin.makeLayout(layout)
ew.threadHandle(threadWorker, start=True, key='thread', args=("Worker",))
appWin.run()
에제 프로그램
화면
전체 소스
import os
import sys
import time
import wx
import ezWxPython as ew
def initCtrls():
global label, runcount
label = ew.getWxCtrl('label')
label.SetBackgroundColour(wx.Colour(200,200,240))
runcount = 0
def onExit(event):
appWin.close()
def onClose(event): #return True if want to exit
rv = appWin.messageYesNo("Alert", "Do you want to quit ?" )
return rv
def onAbout(event):
appWin.messageBox("About", "Thread Demo\nzdiv")
def threadGuiAction(status_text):
def action():
appWin.setStatusText(status_text)
return action
def threadWorker(args):
global runcount
while True:
ew.callAfter(threadGuiAction(args + ": " + str(runcount)))
runcount += 1
time.sleep(0.1)
menu_def = {
"File" : {
"Exit" : [ onExit, wx.ART_QUIT ],
},
"Help" : {
"About" : onAbout
},
}
body_def = [
[ ew.Label("Hello ezWxPython",expand=True,proportion=1,key='label'),
{ 'expand' : True, 'proportion' : 1 } ],
]
status_def = [
["Ready", -1],
]
layout = {
"menu" : menu_def,
"body" : body_def,
"status" : status_def,
}
if __name__ == "__main__":
appWin = ew.WxApp(u"Thread Demo", 320, 240)
appWin.makeLayout(layout)
initCtrls()
appWin.closeHandle(onClose)
ew.threadHandle(threadWorker, start=True, key='thread', args=("Worker",))
appWin.run()