카테고리 없음

ezWxPython : 백그라운드 작업 II (Thread)

zdiv 2019. 4. 10. 00:12

백그라운드 작업하기 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()