윈도우

wxPython 으로 GUI 프로그램 만들기 - wxGlade

ForceCore 2009. 6. 30. 02:01
http://forcecore.tistory.com/1032 1편. 환경 갖추기
http://forcecore.tistory.com/1033
 2편. wxGlade로 틀 잡기
http://forcecore.tistory.com/1036 3편. py2exe로 exe파일로 만들기

wxGlade가 처음에는 구려보이지만, 있는 것들 중 가장 나은것이라는 점을 알 수 있다 -_-;; 해보면...;; 주의할 점은, 한글 지원이 안 된다는 것이다. 아니면 필자가 못하는건가? 처음에 디자인 단계는 모든 것을 영어로 한 뒤, 나중에 코드생성이 된 이후, 코드를 한글로 좀 고쳐주면, python자체는 한글이 안 되는건 아니라 그럭저럭 한글이 되긴 한다.

우선 wxGlade의 리소스 파일이 저장될 곳을 물색해야 한다.
주의할 점은, 저장되는 곳은 절대로 한글이 들어가지 않는 폴더여야 한다는 점이다. 그런 측면에서, 윈도우 사용자 이름이 한글이거나, 바탕화면, 내 문서 같은 곳은 고르면 안 된다 -_-;;

필자는 c:\mod 폴더를 생성했다.

이제 wxGlade를 실행시킨다.


이런 썰렁한 창이 뜬다. 뭘 하란거지? 처음엔 좀 황당하다.

알아두어야 할 것이, 델파이나 비주얼 스튜디오와는 달리, 거의 모든 요소들이 boxSizer라는 것 안에 들어가야 한다는 점이다.

처음에는 wxGlade:Tree 라고 적힌 창에 Application만 있어야 한다.
팔레트 창에서 add a dialog버튼을 누르면 창을 하나 볼 수 있게 된다.


이렇게 되어 있는데.. class는 적당히 MainDialog 이런 식으로 적고 OK를 누른다. wsDialog를 선택하는건 필수;


아무것도 없는 창이 하나 더 보이게 될 것이다. 여기다가 대고 디자인을 하면 되는데, 버튼을 두개 추가하려고 해도 잘... 안 될 것이다. 이유는... 아까도 말 했지만, BoxSizer라는 것을 이용해야 하기 때문이다. 버튼을 혹시 넣으려고 해봤다면 -_- tree에서 오른 클릭을 해서 지우든, 창에서 선택하고 del버튼을 누르든 선택하여 없애라.

이쯤에서 필자의 최종 목표를 미리 밝혀야 할 듯 싶다.


이런 창을 만드는 것이다. 저 구성을 염두에 두고...

다시 원상 복구가 된 뒤 이번에는, BoxSizer를 넣는다. 그리고 메인창에 클릭을 하면...


이런 창이 뜨는데, vertical을 택하고, slot은 2를 선택한다. 왜 2냐면, 필자는 크게 저 그림을 품는 영역과 버튼을 품는 영역을 나누고 싶기 때문이다. 이런식으로 영역 나눔을 먼저 해야지 그 영역에 버튼을 놓든 말든 할 수 있다는 특징이 있다.


창이 이렇게 될 것이다. 빗금친 영역에는 버튼과 같은 것을 놓을 수 있다.

Static Bitmap을 아래에다 놓고, 그림을 불러오자. StaticBitmap버튼을 클릭한뒤 아래 빗금에 클릭하면, 원하는 이미지를 불러올 수 있게 된다.


두둥. 저 창을 닫았다가 다시 켜보자. 닫은 다음에 다시 켜려면, tree에서 dialog에 더블클릭을 하면 된다.


쪼그라들었다 ㅡ,.ㅡ;; 보통은 wxWidget의 (wxPython이 사용하는 라이브러리!) 구성요소들은, 사이즈가 좀 지멋대로다. 일부러 지정해주지 않는한은...

이제쯤 저장하라. 언두 기능이 없어서, 뭔가 잘못해서 큰 덩어리 하나를 실수로라도 삭제하면, 이제껏 한 작업이 통째로 날아가게 된다 -_-;;;;;; 버전 0.6.3 기준임. 버전업되면 생기겠지... OTL

이제 BoxSizer로 6칸짜리 vertical을 윗 영역에 넣자. 창이 너무 쪼그라 들어서, 제대로 안 보일 것이다. 창을 껐다 다시 켠다.


그러면 이렇게 보인다. 아래 다섯칸에는 버튼을 넣는다.


... 문제가 두개 있다.
1. 버튼 가로길이가 너무 작다 -_-
2. 버튼에 여백이 없어서, 창에 찰싹 달라 붙어 있다.


키우고자 하는 버튼을 선택하고, properties창의 layout탭에서 wxEXPAND를 해주면, 늘어날 수 있는 한도까지 쭉 늘어난다.


그 외에, size에 체크박스를 하고 일부러 크기를 입력해주면 크기를 정확하게 넣을 수 있다. 하지만 필자의 의도는, 로고 그림이 커지면 버튼도 같이 커지는 것이므로, 위에 설명한 wxEXPAND면 충분하다. 버튼의 세로 사이즈가 -1로 되어있는데, 이는, 그냥 default치를 사용하는 것이다?

Properties에서 Widget탭을 보면, 버튼에 어떤 글자가 들어가야 하는지 지정해 줄 수 있다. Common의 name항목도 예쁘게 해주어야 한다. 가령, Quit이라고 적힌 버튼은, name이 button_quit 으로 필자가 설정했다.

이제 여백도 넣어볼까... 두번째에 넣었던 버튼용 BoxSizer의 property에서


이렇게 Border를 0이 아닌 값으로 주고, Border중, 여백을 줄 방향에 체크해주면 됨.

이제 enable, disable버튼 두개를 추가해주고 싶은데... 빈 영역에 horizontal BoxSizer를 넣자. 슬롯 두개짜리.


이 버튼들 가로 크기가 동일하고, 가로로 꽉 채웠으면 좋겠는데... 역시 죽어도 안 된다. 오히려, wxEXPAND를 사용하면 세로로는 늘어나는 것을 볼 수 있다. 그 이유는... BoxSizer가 Horizontal이면 버튼은 세로로 expand되고, vertical이면 가로로 expand되기 때문이다. -_-^;; 어쩔 수 없이... 머리를 좀 써서... 버튼 두개만 삭제하고, 버튼이 있던 자리에, 크기1짜리의 vertical BoxSizer를 넣는다 -_-;; 그러면 된다.


모양은 완성됐다. 두둥.

이제 Quit버튼에 들어갈 이벤트 핸들러 (클릭시 일어나면 프로그램이 취할 행동) 를 넣어보자.
Quit버튼을 선택하고 Events의 EVT_BUTTON에
 

on_btn_quit 과 같은 것을 넣어주자. 마우스 오버같은 이벤트는 디텍트 안 되나? 하긴 그런 프로그램은, "보통은" 나오지 않는... 데...;; 예쁜 프로그램을 만들거 아니면.

이제 모양은 다 디자인 했으니 python코드를 생성하라고 해보자.


트리에서, application을 선택하면, 프로퍼티 창에 저런 게 뜬다. Encoding이 좀 기분나쁜 값으로 되어 있는데, 현재로서는 무시하자. 어차피 우리가 코딩을 좀 하면서 수정할 것이다. 그리고 옵션은 원하는 대로 선택하고, Output path의 ...버튼을 클릭하여, 생성될 코드의 이름을 지정해주자. Generate Code버튼을 클릭하면 코드가 나오고...



코드를 실행하면 원하는대로 창이 뜬다. wxGlade에서 보던 것 보다 버튼같은게 테마 적용이 되어 예쁘게 보인다. Quit버튼을 클릭하면, on_btn_quit이 아직 구현되지 않았다고 뜰 것이다.

아까 생성한 스크립트를 이제 텍스트 편집기로 열어보자.

파일 시작 부분에는
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# generated by wxGlade 0.6.3 on Tue Jun 30 00:20:50 2009

import wx

이런게 있는데 iso어쩌구 대신 cp949를 넣어주자. wsGlade에서 하지 않은 이유는? cp949라고하면, "나는 그런 인코딩은 몰라"라고 wxGlade가 우기기 때문이다 -_-;;

코드를 더 읽다보면
        self.button_en = wx.Button(self, -1, "Enable")
        self.button_dis = wx.Button(self, -1, "Disable")
        self.button_run = wx.Button(self, -1, "Run")
        self.button_modhome = wx.Button(self, -1, "Mod Homepage")
        self.button_red2net = wx.Button(self, -1, "red2.net")
        self.button_quit = wx.Button(self, -1, "Quit" )
이런 버튼에 적힐 글귀가 있는 코드가 있는데 그것도 고쳐주자.


한글도 잘만 된다. +_+

    def on_btn_quit(self, event): # wxGlade: MainDialog.<event_handler>
        print "Event handler `on_btn_quit' not implemented"
        event.Skip()

quit버튼을 누르면 구현이 안 됐다고 뜨게 하는 기능은 여기 있다. 여기있는 place holder 코드를 지우고 원하는 기능으로 고친다.

    def on_btn_quit(self, event): # wxGlade: MainDialog.<event_handler>
        self.Close()

창을 닫는 코드를 실제로 넣어 주었다.

다시 실행을 시켜보면, 창은 닫히는데, 검은창은 없어지지 않는다... 원래 그런거지...
필자가 스크립트의 이름을 mod.py 라고 지었기 때문이다.
mod.pyw로 이름을 변경하라. 그러면 땡이다.

다음 시간에는 exe로 컴파일도 해보자.