python gui wxPython을 사용한 사용자 입력 다이얼로그(Dialog) 만들기
python의 gui 툴킷인 wxPython은 mfc와 유사하게 일반 wx.Frame 윈도우와 wx.Dialog 윈도우 두 종류의 윈도우를 생성할 수 있다. 본 포스트는 wx.Dialog를 기반으로 사용자 입력을 받기 위한 다이얼로그 박스를 만드는 예제를 싣고 있다.
wxPython의 설치 방법은 아래 포스트를 참조하자.
common Dialogs - TextEntryDialog
wxPython에는 몇 가지 일반적으로 필요한 다이얼로그 박스들을 제공한다. 색상 선택, 파일 선택, 메시지 다이얼로그 등이 있다. [https://docs.wxpython.org/common_dialogs_overview.html]
그 중 TextEntryDialog을 사용하면 간단하 사용자의 text 입력을 받을 수 있다.
import wx
def get_text():
data = None
dlg = wx.TextEntryDialog(parent=None,message='input text')
try:
if dlg.ShowModal() == wx.ID_OK:
data = dlg.GetValue()
print(data)
finally:
dlg.Destroy()
return data
if __name__ == '__main__':
app = wx.App()
try:
get_text()
#app.MainLoop()
finally:
del app
wxPython은 아래와 같은 순서로 동작한다.
1. wx.App()를 통해 app 객체 생성
2. wx.Frame, wx.Dialog등 window를 생성
3. 이벤트 처리를 위한 함수 등록
4. event loop 실행, Dialog의 경우에는 dlg.ShowModal(), Frame의 경우 app.MainLoop()
TextEntryDialog는 객체 생성 후 showModel을 통해 화면에 보여주고, 리턴 값으로 wx.ID_OK, wx.ID_CANCEL을 돌려 받는다. (mfc의 다이얼로그 박스와 유사하다.) 입력 내용은 wx.TextEntryDialog.GetValue()를 통해 받아올 수 있다.
dialog 사용 후 dlg.Destroy()를 호출해 리소스를 제거하는 것을 잊지 말자. 아래 코드와 같이 with를 사용하면 따로 Destroy()를 호출할 필요는 없다.
def get_text():
with wx.TextEntryDialog(parent=None,message='input text') as
dlg:
if dlg.ShowModal() == wx.ID_OK:
return dlg.GetValue()
return None
코드를 실행하면 아래와 같은 다이얼로그 창이 생성되는 것을 볼 수 있다.
위 TextEntryDialog는 단순히 하나의 text만을 입력으로 받는다. 여러 데이터를 입력으로 받기 위해선 별도의 Dialog를 만들 필요가 있다.
파라미터 입력 다이얼로그 예제
새로운 Dialog는 wx.Dialog를 상속 받아 만들 수 있다.
wx.Dialog class
API는 https://docs.wxpython.org/wx.Dialog.html에 자세히 설명되어 있다.
import wx
class InputDialog(wx.Dialog):
def __init__(self):
wx.Dialog.__init__(self,parent=None,title='ryan\'s
input dlg',size=(300,200))
_sizer = wx.BoxSizer(wx.VERTICAL)
message = wx.StaticText(self,label='please input
params')
# param 1
_param1_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.param1_edit =
wx.TextCtrl(parent=self,name='param1')
_param1_sizer.Add(wx.StaticText(self,label='param
#1'),1, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
_param1_sizer.Add(self.param1_edit,4,wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT,
10)
#param 2
_param2_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.param2_edit =
wx.TextCtrl(parent=self,name='param2')
_param2_sizer.Add(wx.StaticText(self,label='param
#2'),1, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
_param2_sizer.Add(self.param2_edit,4,wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT,
10)
# OK, CANCEL buttons
_btns_sizer = wx.BoxSizer(wx.HORIZONTAL)
okbtnSizer =
self.CreateStdDialogButtonSizer(wx.OK)
canceltnSizer =
self.CreateStdDialogButtonSizer(wx.CANCEL)
_btns_sizer.Add(okbtnSizer,1,
wx.ALIGN_CENTER_VERTICAL, 0)
_btns_sizer.Add(canceltnSizer,1,wx.ALIGN_CENTER_VERTICAL, 0)
#
_sizer.Add(message,1,wx.ALIGN_CENTER|wx.TOP,5)
_sizer.Add(_param1_sizer,1,wx.ALIGN_CENTER|wx.TOP,5)
_sizer.Add(_param2_sizer,1,wx.ALIGN_CENTER|wx.TOP,5)
_sizer.Add(wx.StaticLine(self,size=(250,2)),0,wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM,5)
_sizer.Add(_btns_sizer,1,wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM,5)
self.SetSizer(_sizer)
def GetValue(self):
return self.param1_edit.GetLineText(0),
self.param2_edit.GetLineText(0)
__init__에서 다이얼로그에 컴포넌트를 추가해 ui를 구성하였으며, GatValue() 함수를 만들어 입력된 값들을 받아갈 수 있게 구성했다.
ui 구성에는 아래와 같은 요소들이 사용되었다.
1. Sizer
Sizer는 윈도우 컴포넌트(button, text, edit box, 등)를 화면에 배치하는데 사용되는 일종의 컨테이너이다. 안드로이드 등에서 사용되는 layout과 유사하다.
Sizer는 BoxSizer, StaticBoxSizer, GridSizer,FlexGridSizer등이 있다. 이는 컴포넌트들을 어떻게 구성할지에 따라 구별된다.
Sizer는 Sizer생성후 Add를 통해 window 컴포넌트 및 Sizer를 추가할 수 있다. 이때 컴포넌트의 정렬 방법과 위치 등을 조정할 수 있다.
추가 설명은 https://docs.wxpython.org/sizers_overview.html 에서 확인할 수 있다.
본 포스트의 예제에서는 아래 그림과 같이 구성되어 있다.
2. wx.StaticText
wx.StaticText class는 하나 또는 여러 줄의 글(read-only)을 화면에 보여주는데 사용한다. 아래와 같이 생성할 수 있다.
wx.StaticText(parent, id=ID_ANY, label="", pos=DefaultPosition, size=DefaultSize, style=0, name=StaticTextNameStr)
파라미터
- parent ( wx.Window ) - 부모 window, None이면 안된다.
- id ( wx.WindowID ) - 컨트롤 식별자.
- label ( string ) - 텍스트 레이블, 화면에 보여줄 텍스트.
- pos ( wx.Point ) - 창 위치.
- size ( wx.Size ) - 창 크기.
- style ( long ) - 창 스타일.
- wx.ALIGN_LEFT: 텍스트를 왼쪽으로 정렬.
- wx.ALIGN_RIGHT: 텍스트를 오른쪽으로 정렬.
- wx.ALIGN_CENTRE_HORIZONTAL: 텍스트 가로 맞춤.
- wx.ST_NO_AUTORESIZE: 컨트롤의 크기가 변경되지 않는다.
- wx.ST_ELLIPSIZE_START: 텍스트 길이가 초과하는 경우 레이블 시작 부분을 줄임표로 바꾼다.
- wx.ST_ELLIPSIZE_MIDDLE: 텍스트 길이가 초과하는 경우 레이블 중간을 줄임표로 바꾼다.
- wx.ST_ELLIPSIZE_END: 텍스트 길이가 초과하는 경우 레이블 끝을 줄임표로 바꾼다.
- name ( string ) - window 이름.
3. wx.TextCtrl
wx.TextCtrl class는 텍스트를 화면에 보여주거나 편집하는데 사용되며, 아래와 같이 생성할 수 있다.
wx.TextCtrl(parent, id=ID_ANY, value="", pos=DefaultPosition,size=DefaultSize, style=0, validator=DefaultValidator,name=TextCtrlNameStr)
파라미터
- parent ( wx.Window ) - 부모 window, None이면 안된다.
- id ( wx.WindowID ) - 컨트롤 식별자.
- value ( string ) - 텍스트.
- pos ( wx.Point ) - TextCtrl 위치.
- size ( wx.Size ) - TextCtrl 크기.
- style ( long ) - window 스타일.
- validator ( wx.Validator ) - window 유효성 검사기.
- name ( string ) - window 이름.
4. wx.StaticLine
wx.StaticLine class는 다이얼로그에 라인을 그리는데 사용되었다.
wx.StaticLine(parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize, style=LI_HORIZONTAL, name=StaticLineNameStr)
파라미터
- parent ( wx.Window ) - 부모 window, None이면 안된다.
- id ( wx.WindowID ) - 컨트롤 식별자.
- pos ( wx.Point ) - Line 위치.
- size ( wx.Size ) - Line 크기.
- style ( long ) - Line 스타일.(wx.LI_HORIZONTAL, wx.LI_VERTICAL)
- name ( string ) - window 이름.
5. CreateStdDialogButtonSizer
wx.Dialog.CreateStdDialogButtonSizer는 다이얼로그에서 사용되는 표준 버튼을 생성한다. 표준 버튼은 wx.OK, wx.CANCEL, wx.YES, wx.NO, wx.APPLY, wx.CLOSE, wx.HELP, wx.NO_DEFAULT이 있다.
CreateStdDialogButtonSizer를 사용하면 별도의 버튼 이벤트 핸들러를 Bind하지 않아도 showModel()에서 wx.OK, wx.CANCEL등이 반환된다.
실행 결과
예제로 구현한 다이얼로그는 아래 코드와 같이 사용할 수 있다.
def get_userparam():
param1 = None
param2 = None
dlg = InputDialog()
try:
if dlg.ShowModal() == wx.ID_OK:
param1, param2 = dlg.GetValue()
print('param1:',param1,',
param2:',param2)
finally:
dlg.Destroy()
return param1,param2
if __name__ == '__main__':
app = wx.App()
try:
get_userparam()
finally:
del app
실행하면 아래와 같은 다이얼로그가 생성된다.
hello, wxPython을 각각 입력하고, OK 버튼을 클릭하면 아래와 같이 출력 된다.
param1: hello , param2: wxPython
댓글
댓글 쓰기