카테고리 없음

ezWxPython : 윈도우 만들기

zdiv 2019. 4. 9. 23:31

다음 예제와 같이 WxApp 를 이용하여 응용프로그램을 생성한다. 이 때, 화면 구성은 미리 정의된 layout 객체를 이용한다.

import ezWxPython as ew
​
appWin = ew.WxApp(u"Frame Demo", 320, 240)
appWin.makeLayout(layout)
appWin.run()


WxApp는 윈도우 타이틀, 가로 크기, 세로 크기의 세 개 파라미터를 입력으로 받는다. 여기에서 사용자의 입력에 대해서는 이벤트 Driven 방식으로 처리하므로, 다음에 설명할 레이아웃(layout) 구성 시에 이벤트 핸들러를 등록함으로써. GUI 이벤트를 받아서 처리할 수 있다.

또한, 사용자의 입력과 무관하게 주기적으로 처리해야하는 작업에 대해서는, Idle 이벤트 핸들러나 Timeout 핸들러를 등록하여 처리하면 되는데, 이에 대해서는 나중에 별도의 챕터에서 설명하도록 한다.

layout 객체는 다음과 같이 4가지 요소로 구성되는데, 각각의 구성 요소에 대해서는 별도의 강좌를 통해서 자세히 설명하도록 하고, 여기서는 간단한 구조만 살펴 보도록 한다.

layout = {
    "menu"   : menu_def,
    "tool"   : tool_def,
    "body"   : body_def,
    "status" : status_def,
}


여기에서 'menu', 'tool', 'body', 'status' 는 윈도우를 구성하기 위한 4가지 기본 요소로써, 항상 모두 정의해서 사용할 필요는 없으며, 필요한 항목에 대해서만 선택적으로 정의해서 사용하면 된다.

다음 그림은 위에 정의된 4가지 요소를 포함하는 기본적인 윈도우를 나타낸다.

메뉴 구성


메뉴는 파이썬의 dict 구조를 이용해서 만드는 데, "메뉴 이름" : 핸들러 와 같은 형태로 구성한다. 아이콘을 가지는 메뉴의 경우에는 "메뉴 이름" : [ 핸들러, 아이콘 ]의 형태로 구성할 수 있다. 하위 메뉴가 있는 경우에는 "메뉴 이름" : { 서브 메뉴 } 의 형태로 구성한다.

menu_def = {
    "File" : {
        "Exit" : [ onExit, wx.ART_QUIT ],
    }, 
    "Help" : {
        "About" : onAbout
    },
}


아이콘은 wx.art에 미리 정의되어 있는 아이콘을 사용할 수도 있으며, 외부 png 파일 등의 아이콘을 사용할 수 도 있다. 자세한 내용은 메뉴 구성관련 챕터를 참고하도록 한다.

툴바 구성


툴바는 파이썬의 list 구조를 이용해서 만드는 데, 하나의 툴바 아이템에 대해서 "아이콘", "핸들러", "텍스트", "툴팁"]과 같은 형태로 구성하고, 이를 여러개 리스트로 구성함으로써 툴바를 만들 수 있다. 여기에서 "텍스트" 와 "툴팁"은 필요한 경우에만 정의해서 사용할 수 있으며, 핸들러를 None으로 정의하여 해덩 툴 버튼을 Disable 상태로 만들 수 있다.

tool_def = [
    [exit_png, onExit, "Exit", "Close Application" ],
    [None],
    [new_png,   onNone, "New", ],
    [save_png,  None,   "Save", ],
    [copy_png,  onNone, "Copy", ],
    [paste_png, onNone, "Paste", ],
    [None],
    [question_png, onAbout, "About", ],
]


아이콘은 메뉴에서와 동일하게 wx.art 에 정의된 아이콘을 사용하거나, 외부 파일을 사용할 수도 있다.

사용자 영역 구성


사용자 영역은 파이썬의 list 를 이용하여 구성하며, 하나의 세로 Layout과 여기에 포함된 여러 개의 가로 Layout으로 구성된다. 만일, 가로 Layout 내에 속한 세로 Layout 이 필요한 경우에는 Panel 컨트롤을 이용하여 사용자 영역을 구성하는 방법과 동일하게 구성할 수 있다. 이에 대해서는 레이아웃 챕터를 참고하도록 한다.

body_def = [
    [ ew.Text("Multiline\nText\nEditor",multiline=True,expand=True,proportion=1,key='text'), 
        { 'expand' : True, 'proportion' : 3, 'border' : 0 } 
    ],
]

상태바 구성


상태바는 툴바와 유사한 구성을 가진다. 즉, 하나의 상태 아이템에 대해서 ["텍스트", 크기]의 형태로 구성할 수 있으며, 이를 여러개 리스트로 구성함으로써 상태바를 만들 수 있다. 상태 아이템의 크기를 결정하는 '크기' 항목은 양의 값을 가지는 경우에는 해당 상태 아이템의 가로 폭을 픽셀 단위로 절대 값으로 지정할 수 있으며, 음의 값을 가지는 경우에는 상대적인 크기로 지정할 수 있다. 즉, -2의 값을 가지는 아이템은 -1을 가지는 아이템에 비해 2배의 크기를 가지게 된다.

status_def = [
    ["Ready", -1],
]


WxApp 클래스에 정의된 SetStatusText("텍스트", 인덱스) 함수를 이용하여, 상태 아이콘의 텍스트 값을 변경할 수 있다.

예제 프로그램

화면

전체 소스

import os
import sys
import wx
import ezWxPython as ew

exit_png = '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'
save_png = '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'
new_png  = 'eJwBbQKS/YlQTkcNChoKAAAADUlIRFIAAAAgAAAAIAgGAAAAc3p69AAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIPSURBVHja5JdLT8JAEMdnuhUqaKIXhZOaED+BnnnoTS8maALBbydWY9T6idQjatTEoola6mxlm1K6pYVCTdzkn+1jdve3M/tE27YhzaR6XxBRvby+Nuhhz+71IB4at0ZQEMGyrJujer1OH76l1qLj/EGI0iIB2JOmTqdjt3X9iupjYQBcqu+7Jshu7+65R6L3n8ptrK/ByekptJpNqFUqBye6ftFqNA7ptyUrp/jeUbhdURRHjLGRErZOBZQ/v7xCoVCAWrnsQIR5QpH94L3nlfJ8lISdU467MZuFh8cnKBaLIyFCAeJKpGx2DuY1zYXYoXC0z84CIaQAjHG3YnQxdOcCYyrkchos5PNuOHar1QP9/Nzwzzw1YDQNeCBqQvi13SyVgHoL6JmcPZrSxzQwM5nMPr3Ok97kAG4IlFgAZA3mWxe2t7YcBaXeb+e0iAAxPUC23Y93MEliMHoXnMLqivAuhodA9CgmQJ9CvuJFWYon8UBYPWEQcgCG7sCa2WbkDwEkBIDjhYDNfjse9kCKAJg6gPLfPfAHxgDrbyXTnYgzCsE4AHx/T8wBYwAwvoYn1n7KIYgH0DfmB82kbk0uQADIEIA4Xk9jLfDWLQWgJs0rw1hwjk9J3RsRxQHHHPrldTMZLFG2QVpObC8evDy+8EsX6VW06weYoyxPykxp4fskdUlfMoCZXctFuz8CDADTDemmZn/jMwAAAABJRU5ErkJggp2IF1E='
copy_png = 'eJwBXgOh/IlQTkcNChoKAAAADUlIRFIAAAAgAAAAIAgGAAAAc3p69AAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAMASURBVHjarFdRTxpBEJ7ZPSm22uCDBEiTamL/gX0RqaTpG32hEk1M+usaUQwofepTH/s7irQ2gdSGYm2NeGxnl7vj7rjDuz2HTBb2bve+mfnm2wMBwGidnbUBsSLGYxAQZvIKAkME0zQ/7tVqNZq4gwewZQIg4liv1xOHR0entJYnfbhBnqY91Y+vnXNKBAbHT/esrz2HD/U6vD84gNflcrXeaHw+2N9/kyQTTObVTjtnTLnhc3teLaBxMPgNuVwOyqXSTqPZ7NL0QhIAjiFtzjgH9LmaswDI/Cw+XoTLy1+Qz+fhVbGYP2m1OrogPAAYJ5KxEOfT0jxKpWBpecnJxM72doF4dKEDwrAKPIkOeSgHUEzmX2xswOHxscqEXDWmzpGcIFslf0I+iA/A4QCGA6Dpq+s/8HJzU7nfJBCylF4G7BIgCwUgQ775e6Pc1RoqC9nsKozpO5WhJ6w5t26Q9Xer1Wc0juYCQMYh7Pk2Af2tac+Z5h3s7e4Gruv3+9mTZrND4rXmB+EhIccJ4qiu2hOZI5TfL35Ap/sNOuddpSnSpG5ks1koFYsFatmZbvG2IWeq3WI5Zy4OzdeN0tbWDAhvGzLU8mkbc8fn6EbBrRvMT0IdDwwgom74SIiJDhZUXSQUIaLqxkwb6prcnFPUQqDStXt1YyJ+qRkhEnGj9gRA9UepA+Je3bDV1/DuRuTRhSA1weoMR9rn6EawFHO018aou6sLLH0Q4TeD/6LhXFAAOGgg8Bzn7gxEPgsYY4Ebxs2E3YJxYjAmR624Om23lxUzI6yWtaQXUxCuezOZDNWXANBHYLwM3L6rVndoXAngTZAtkIh8elup2EewY+bYVNKGgLEAXMv3UfKLiGtWZOSL6TTc3o6cLKhjOC5/LACjuG8x0wcJsGktqYMR+DO3DXVeKRGTSFdCAEl1Qx/AQ+iGNWoBeAjdsPfQAkC6MSTdeBpVN/wZkHI9HA6/SAbrwM+Qr8fQjSCT/yV/knd1Nliw/oCkEvBXpk2e0//+CzAAX7xYJCFPmcoAAAAASUVORK5CYIL9No9v'
paste_png = 'eJwBugRF+4lQTkcNChoKAAAADUlIRFIAAAAgAAAAIAgGAAAAc3p69AAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAARcSURBVHjarFdNbFRVFP7ue68DFdTS0rEFI5VgCIo73NAWiJGEpLNoK2pCJODKjY1bEhMWxIX7blxgQlAJQutogitXLhrixp1EE6NFw8KBap1qOz/v3uM59/3MzGPe/PY2Z1563z33fOc7P/c+hfbDW1xczDuOkyMiO6GUgjHmzsLCwhz/66OP4XWwZlBrnZufnxejdoLBYOn27Zy8Y9noB4ASENcunf5KgWYoNAAQHFPB+sGLODU9Ba2rLBpGGAhZEBDKcbFy93sM/XoNxsmE2/EvvyOoby5+9O1sO4Y864XRM7NvL0AzAFZkiuWFj6vfrWFoz9O4v/q7BZXEfmDiOfi+xuz593m1Z7GxI3AZQP6zxZlOGBIAO8W7Hdkj+PnOFUbv2RgLAFInMTKyVyA1VR4eGeE1Lh788HUIgEDGx+HcZcuY7N0JAM4osPcljrF471qDmm3uzzzCx59chyLdVFmM7888hOZtDLkhAG334gnEMWmXhKQIploVHJDoSRiIHLw48BNeGrhnaW20THEYjHKgSbSM1bR/lTI7U+28CmQ/XRUlCjCrwICGsOE0Rp4YpjBCfgMQCjeSEOjyBkx5szsAhjPdFoGidOJ4ocOGHw6fQHHwIONIhoZsGH65t4XhMx9i6Yz5UwUgC6/PzT7Lz2pTAMoyUGESxTuTGjrJhc3MM9hg42/kTndc64VCIXtraWn1zbNnJ5IgQgY46fxKEAKkMyDeiNekgz1+W71vK6Y5WYTnJw7g0xs3cP7cOUxPTu77gkG8lQDhREmodcWGQEC0FDKxEal3ES8h0XzUsNbX/8HY2Bimjx+3IHh6oAGAOO1LCIjaClGtIqTjOS4nakLsXAhA+Bl8YhBra39hfHwcJ5iJW8vLMYiAAal7BkDtvNfMVB0Ax+UacVLErYVmRyaD3U/ujpk4OTW1bzmffyAgvCi7ta1dE3SllLgqbjJkajlim1baWgrmXzh0CJ/fvGlVBLrYkJzgMcqyKwSgbA7oqKIpvQzr7HOcVToAnt7471+8cuyYleQwAZMZL6xe+JWgClSqdasVKQYh4C6YBkBQljZLVuodEO1sdjRuYl6UA1W/HHhHLQA8loRuWrTQ7CAQXZXaimMGgNQYhIkYl6FYV93cPtRjW3tRg/GrURK2OMTkvmAZCFe5DvodtRBIFcTnELVIwroccNT2AJAhDEiJkWqdhJRIwm1igJuzDUHtKE4HYOLEU9vGAEkIotOwxaZsnEwtk7eNAcRJ2CL+IQOoKyVpRNTDNbx5ElZLbZWJotXRbi76hSAAqLhZXsEff0+2s264WWWGdiJ7JDDqugrUpf1k5xQApQ+u332Xn3s7+VI69eprE+9N+1cDAC56QNDwFINbLPLlUejgGu0effnoaAPtqrdKcOruC90MdhnjX+bzPzKEp+o/1bphwGEpFosr71y4MKd6yKA9LHKvG+rBgbjvsTwS5nvZQK5Su+Qs76P8hTYpu63/BRgAcIZyeXbLXkIAAAAASUVORK5CYIKP4TC4'
question_png = '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'

def setStatusText(text,index=0):
    appWin.setStatusText(text,index)

def onExit(event):
    appWin.close()

def onAbout(event):
    appWin.messageBox("About", "Frame Demo\nzdiv")

def onNone(event):
    pass

menu_def = { 
    "File" : { 
        "Exit" : [ onExit, wx.ART_QUIT ],
    }, 
    "Help" : { 
        "About" : onAbout 
    },
}

tool_def = [
    [exit_png, onExit, "Exit", "Close Application" ],
    [None],
    [new_png,   onNone, "New", ],
    [save_png,  None,   "Save", ],
    [copy_png,  onNone, "Copy", ],
    [paste_png, onNone, "Paste", ],
    [None],
    [question_png, onAbout, "About", ],
]

body_def = [
    [ ew.Text("Multiline\nText\nEditor",multiline=True,expand=True,proportion=1,key='text'), 
        { 'expand' : True, 'proportion' : 3, 'border' : 0 } 
    ], 
]

status_def = [
    ["Ready", -1],
]

layout = {
    "menu"   : menu_def,
    "tool"   : tool_def,
    "body"   : body_def, 
    "status" : status_def, 
}

if __name__ == "__main__":
    appWin = ew.WxApp(u"Frame Demo", 320, 240)
    appWin.makeLayout(layout)
    appWin.run()