상세 컨텐츠

본문 제목

12. GUI(윈도우 프로그래밍)

Python

by evaseo 2021. 4. 29. 16:27

본문

1.    wxPython모듈 사용 - import wx: 라이브러리 로딩

(1)     Python에 기반한 GUI toolkit

(2)     Python 언어를 이용해서 GUI를 간단하고 빠른 시간에 제작 가능하도록 도와준다.

(3)     GUI 라이브러리인 wxWindows Python에서 지원이 가능하도록 c++ 로 제작되었으며, 크로스 플랫폼 toolkit 이다.

(4)     Index of /Phoenix/snapshot-builds (wxpython.org)에서 wxPython-4.1.2a1.dev5103+4ab028d7-cp38-cp38-win_amd64.whl다운

 

2.    실행 메소드

(1)     wx.App(): 어플리케이션 객체를 생성

(2)     Show(): 생성한 윈도우 출력

(3)     app.MainLoop()

1)       이벤트 루프 생성

2)       app만들어서 창을 띄우는 것

3)       무한루프에 빠지는 것 - x를 누르면 멈춤

<cmd창에서 실행 시>


3.    윈도우 프레임 생성방법 2가지

(1)     wx.Frame(None, title): 어플리케이션 객체안에 윈도우 프레임 생성


import wx

app = wx.App(False)
frame = wx.Frame(None, wx.ID_ANY, 'Hi')
frame.Show(True)
app.MainLoop()
실행결과

(2)     wx.Frame을 상속받는 클래스 생성

1)       클래스 내에서 self.Show() 선언

2)       클래스 밖에서 다음 블록 선언: Ex는 클래스 이름.


3)       생성자

        부모의 생성자를 상속받음

        추가로 title, size, 위치(pos) 등을 설정

import wx
import wx.xrc

class MyFrame1 ( wx.Frame ):
    
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"연습", pos = wx.DefaultPosition, size = wx.Size( 313,187 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )​

4.    layout

(1)     wx.Panel()

1)       윈도우 창에 넣을 공간(패널) 생성

2)       panel위에 여러 layout을 올려놓는다.

3)       구역을 나누는 역할

(2)     wx.BoxSizer: 기본 레이아웃 관리자

1)       sizer클래스: 레이아웃 디자인하는 관리자

2)       각각의 layout들을 배치

        wx.BoxSizer(wx.HORIZONTAL)

        wx.BoxSizer(wx.VERTICAL)

3)       layout삽입: BoxSizer 객체 명.Add(삽입대상명,차지할 비율,[wx.EXPAND])

4)       BoxSizer 설정 적용: self.SetSizer(BoxSizer 객체 명)

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        super(MyFrame, self).__init__(parent, title = title, size=(300, 350))
        
        panel1 = wx.Panel(self, -1, style = wx.SUNKEN_BORDER)
        panel2 = wx.Panel(self, -1, style = wx.SUNKEN_BORDER)
        
        panel1.SetBackgroundColour('BLUE')
        panel2.SetBackgroundColour('red')
        
        box = wx.BoxSizer(wx.HORIZONTAL) #(wx.VERTICAL)
        box.Add(panel1,1,wx.EXPAND)
        box.Add(panel2,1,wx.EXPAND)
        #box안에 panel1과 panel2를 1:1로 나눠가진 것 
        
        self.SetSizer(box)
        
        self.Center()
        self.Show()

if __name__ == '__main__':
    app = wx.App()
    MyFrame(None, title = '연습')
    app.MainLoop()​
실행결과

(3)     텍스트 추가

1)       텍스트 박스 – TextCtrl

        싱글라인

i.     panel 미사용: TextCtrl(self)

ii.    panel 사용: TextCtrl(wx.Panel())

        멀티라인

i.     panel 미사용: wx.TextCtrl(self, style = wx.TE_MULTILINE)

ii.    panel 사용: wx.TextCtrl(wx.Panel(), style = wx.TE_MULTILINE)

2)       고정 텍스트 - StaticText

        panel 미사용: wx.StaticText(self, label = “ “, [size = (너비, 높이),pos = (왼쪽에서 떨어진 거리, 위에서부터 떨어진 거리)])

        panel 사용: wx.StaticText(wx.Panel(), label = “ “, [size = (너비, 높이),pos = (왼쪽에서 떨어진 거리, 위에서부터 떨어진 거리)])

# 2. 라벨과 텍스트박스 사용
panel = wx.Panel(self)
#밑에 panel을 깔고 그위에 id, pwd 입력
#보이기만 하니깐 이름은 안줌
wx.StaticText(panel, label = 'i d : ', pos = (5, 5)) #일방적인 텍스트 뿌려주기
# 왼쪽에서 5 위에서 5 떨어진 곳에 id띄우기
wx.StaticText(panel, label = 'pwd : ', pos = (5, 40))

#이름을 줌(self가 붙어서 이 클래스 내에서는 유효, 이 클래스 내에서 호출가능)
self.txtId = wx.TextCtrl(panel, pos = (40, 5))
self.txtPwd = wx.TextCtrl(panel, pos = (40, 40), size = (200, -1))
#size = (너비, 높이),pos = (왼쪽에서 떨어진 거리, 위에서부터 떨어진 거리): 위치
#-1은 시스템이 자동 설정 해줌​

(4)     버튼

1)       panel 미사용: wx.Button(self, label = ' ', [size = (너비, 높이),pos = (왼쪽에서 떨어진 거리, 위에서부터 떨어진 거리)])

2)       panel 사용: wx.Button(panel, label = ' ', [size = (너비, 높이),pos = (왼쪽에서 떨어진 거리, 위에서부터 떨어진 거리)])

#3. 버튼 - 버튼 레이아웃만
#이름을 줌(self가 안붙어서 이 메소드 내에서만 유효, 다른메소드에서 사용불가)
btn1 = wx.Button(panel, label = '일반버튼', pos = (5, 100))
btn2 = wx.Button(panel, label = '일반버튼', pos = (100, 100))
btn3 = wx.Button(panel, label = '종료', pos = (200, 100))​

(5)     버튼 이벤트 처리

1)       id 미사용

        형식: 버튼 명.Bind(wx.EVT_BUTTON, self.이벤트 메소드)

        id를 미사용 시 여러 개의 버튼에 각기 다른 이름의 이벤트 메소드를 따로 설정

2)       id 사용:

        형식:
버튼 명.id = ?
버튼 명.Bind(wx.EVT_BUTTON, self.이벤트 메소드)

        id사용할 땐 여러 개의 버튼에 같은 이름의 이벤트 메소드를 설정가능. 메소드 블록안에서 id별로 다른 이벤트 설정

#4-1. 버튼에 대한 이벤트 처리작업1
btn1.Bind(wx.EVT_BUTTON, self.btn1Method)
btn2.Bind(wx.EVT_BUTTON, self.btn2Method)
btn3.Bind(wx.EVT_BUTTON, self.btn3Method)

#4-2. 버튼에 대한 이벤트 처리작업2
btn1.id = 1
btn2.id = 2
btn3.id = 3
btn1.Bind(wx.EVT_BUTTON, self.onClickMethod)
btn2.Bind(wx.EVT_BUTTON, self.onClickMethod)
btn3.Bind(wx.EVT_BUTTON, self.onClickMethod)​

3)       event handler method: 이벤트 처리 메소드

        반드시 argument self말고 하나 더 있어야한다.

        event가 발생하면 event 정보를 받을 수 있는 역할로 argument가 하나 더 있어야한다.

        명칭은 자유롭게 설정 가능

def abc(self): #일반메소드
	print('일반메소드')

def btn1Method(self, event): 
    #이벤트 처리 메소드 . event handler 메소드는 반드시 argument가 self말고 하나더 있어야한다.
    #event가 발생하면 event 정보를 받을 수 있는 역할로 argument가 하나 더 있어야한다. 명칭은 꼭 event가 아니어도 된다.
    print('버튼1을 누르다니')
    imsi = self.txtId.GetValue()
    self.txtPwd.SetLabelText(imsi)​

(6)     메시지 박스

1)       버튼 타입

        wx.OK: 확인버튼

        wx.YES_NO: /아니오 버튼

        OK, YES, NO등은 ID => wx.ID_ OK, wx.ID_YES, wx.ID_NO

2)       wx.MessageDialog

        panel 미사용 생성: wx.MessageDialog(self, ‘내용’, '제목', 버튼타입)

        panel 사용 생성: wx.MessageDialog(wx.Panel(), ‘내용’, '제목', 버튼타입)

        모달창 보여주기: 모달창 생성 명.ShowModal()

        종료: 모달창 생성 명.Destroy()

msgDial = wx.MessageDialog(self,'메세지', '제목', wx.OK)
msgDial.ShowModal()
msgDial.Destroy()​

3)       wx.MessageBox('내용','제목', 버튼타입) – 생성, 보여주기, 종료 한번에 해결

(7)     라디오버튼

1)       라디오버튼 값 리스트: 라디오버튼 객체 이름Choices = [ u"+", u"-", u"*", u"/" ]

2)       라디오버튼 생성: wx.RadioBox( )

3)       기본 선택 값: 라디오버튼 객체 이름.SetSelection( 리스트 요소 번호 )

4)       라디오버튼의 값 얻기: 라디오버튼 객체 이름.GetStringSelection()

rdoOpChoices = [ u"+", u"-", u"*", u"/" ]
self.rdoOp = wx.RadioBox( self.m_panel6, wx.ID_ANY, u"연산자 선택", wx.DefaultPosition, wx.DefaultSize, rdoOpChoices, 1, wx.RA_SPECIFY_ROWS )
self.rdoOp.SetSelection( 0 )
bSizer8.Add( self.rdoOp, 1, wx.ALL, 5 )​
실행결과

(8)    

1)       표 생성: wx.ListCtrl()

2)       컬럼 추가: 표 객체명.InsertColumn(컬럼순서(0부터), '컬럼이름',[사이즈 등])

3)       행 추가: 표 객체명.InsertItem(1000, 0) – 최대 1000개 행

4)       내용 입력: 표 객체명. SetItem(행 번호, 열 번호, ‘내용’)

5)       표 내용 전체삭제: 표 객체명.DeleteAllItems()

self.lstGogek = wx.ListCtrl( self.m_panel3, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT )
bSizer4.Add( self.lstGogek, 1, wx.ALL|wx.EXPAND, 5 )

#lstGogek 객체에 제목
self.lstGogek.InsertColumn(0, '고객번호', width=100)
self.lstGogek.InsertColumn(1, '고객명', width=100)
self.lstGogek.InsertColumn(2, '고객전화번호', width=100)

def DisplayData(self, no):
    try:
        conn = MySQLdb.connect(**config)
        cursor = conn.cursor()
        sql = "select gogek_no, gogek_name, gogek_tel from gogek where gogek_damsano={}".format(no)
        #print(sql)

    cursor.execute(sql)
    datas = cursor.fetchall()

    self.lstGogek.DeleteAllItems() #ListCtrl의 초기화

    for d in datas:
        i = self.lstGogek.InsertItem(1000, 0) # ListCtrl의 최대 행 수를 적어줌
        self.lstGogek.SetItem(i, 0, str(d[0]))
        self.lstGogek.SetItem(i, 1, str(d[1]))
        self.lstGogek.SetItem(i, 2, str(d[2]))​

(9)     관련 메소드

1)       값 얻을 곳 이름.GetValue(): 텍스트 박스의 값을 얻는 메소드

2)       입력할 곳 이름.SetLabel[Text](입력할 값): text를 입력하는 메소드 

3)       이벤트 받는 매개변수명.GetEventObject().id: 이벤트 실행 대상의 id 반환 메소드

4)       적용객체명.SetBackgroundColour(‘color’): 배경색 지정 메소드

5)       적용객체명. SetFocus(): 마우스 커서를 설정하는 메소드 - UX/UI:사용자 편의

def onClickMethod(self, event):
    print('onClick')    
    print(event.GetEventObject().id)

    if event.GetEventObject().id == 1:
    	self.txtId.SetLabelText('kbs')

    elif event.GetEventObject().id == 2:
    	self.txtPwd.SetLabelText('mbc')   

    else:
    	self.Close()​

실행결과

5.    wxformbuilder

(1)     GUI를 좀 더 편리하게 사용하는 디자인 툴

(2)     http://sourceforge.net/projects/wxformbuilder/ 에서 윈도우 운영체제용 다운로드 3.5

종합 예제1)

#wxformbuilder로 만들기

import wx
import wx.xrc

class MyFrame1 ( wx.Frame ):
    
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"연습", pos = wx.DefaultPosition, size = wx.Size( 313,187 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
        
        #self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) - 명령 안먹힘
        self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_MENU ) )
        
        bSizer1 = wx.BoxSizer( wx.VERTICAL )
        
        self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText1 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"이름:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText1.Wrap( -1 )
        bSizer2.Add( self.m_staticText1, 0, wx.ALL, 5 )
        
        self.txtName = wx.TextCtrl( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.txtName, 0, wx.ALL, 5 )
        
        
        self.m_panel1.SetSizer( bSizer2 )
        self.m_panel1.Layout()
        bSizer2.Fit( self.m_panel1 )
        bSizer1.Add( self.m_panel1, 0, wx.ALL|wx.EXPAND, 5 )
        
        self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText2 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"나이:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText2.Wrap( -1 )
        bSizer3.Add( self.m_staticText2, 0, wx.ALL, 5 )
        
        self.txtAge = wx.TextCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer3.Add( self.txtAge, 0, wx.ALL, 5 )
        
        self.btnOk = wx.Button( self.m_panel2, wx.ID_ANY, u"확인", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer3.Add( self.btnOk, 0, wx.ALL, 5 )
        
        
        self.m_panel2.SetSizer( bSizer3 )
        self.m_panel2.Layout()
        bSizer3.Fit( self.m_panel2 )
        bSizer1.Add( self.m_panel2, 0, wx.EXPAND |wx.ALL, 5 )
        
        self.m_panel3 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer4 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText3 = wx.StaticText( self.m_panel3, wx.ID_ANY, u"결과:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText3.Wrap( -1 )
        bSizer4.Add( self.m_staticText3, 0, wx.ALL, 5 )
        
        self.staShow = wx.StaticText( self.m_panel3, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.staShow.Wrap( -1 )
        bSizer4.Add( self.staShow, 0, wx.ALL, 5 )
        
        
        self.m_panel3.SetSizer( bSizer4 )
        self.m_panel3.Layout()
        bSizer4.Fit( self.m_panel3 )
        bSizer1.Add( self.m_panel3, 0, wx.EXPAND |wx.ALL, 5 )
        
        
        self.SetSizer( bSizer1 )
        self.Layout()
        
        self.Centre( wx.BOTH ) # = center
        
        # Connect Events
        self.btnOk.Bind( wx.EVT_BUTTON, self.OnClickMethod )
    
    def __del__( self ):
        pass
    
    
    # Virtual event handlers, overide them in your derived class
    def OnClickMethod( self, event ):
        name = self.txtName.GetValue()
        if name == "":
            """m = wx.MessageDialog(self, '이름입력', '알림', wx.OK)
            m.ShowModal()"""
            wx.MessageBox('이름입력','알림',wx.OK)
            return
        age = self.txtAge.GetValue()
        
        self.staShow.SetLabelText(name + age)

if __name__ == '__main__':
    app = wx.App()
    MyFrame1(None).Show()
    app.MainLoop()​
실행결과

    종합 예제2)

import wx
import wx.xrc

class MyFrame2 ( wx.Frame ):
    
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 393,317 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
        
        #self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
        self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_MENU ) )
        
        bSizer5 = wx.BoxSizer( wx.VERTICAL )
        
        self.m_panel4 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer6 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText5 = wx.StaticText( self.m_panel4, wx.ID_ANY, u"숫자1:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText5.Wrap( -1 )
        bSizer6.Add( self.m_staticText5, 0, wx.ALL, 5 )
        
        self.txtNum1 = wx.TextCtrl( self.m_panel4, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer6.Add( self.txtNum1, 0, wx.ALL, 5 )
        
        
        self.m_panel4.SetSizer( bSizer6 )
        self.m_panel4.Layout()
        bSizer6.Fit( self.m_panel4 )
        bSizer5.Add( self.m_panel4, 0, wx.EXPAND |wx.ALL, 5 )
        
        self.m_panel5 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer7 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText6 = wx.StaticText( self.m_panel5, wx.ID_ANY, u"숫자2:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText6.Wrap( -1 )
        bSizer7.Add( self.m_staticText6, 0, wx.ALL, 5 )
        
        self.txtNum2 = wx.TextCtrl( self.m_panel5, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer7.Add( self.txtNum2, 0, wx.ALL, 5 )
        
        
        self.m_panel5.SetSizer( bSizer7 )
        self.m_panel5.Layout()
        bSizer7.Fit( self.m_panel5 )
        bSizer5.Add( self.m_panel5, 0, wx.EXPAND |wx.ALL, 5 )
        
        self.m_panel6 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer8 = wx.BoxSizer( wx.HORIZONTAL )
        
        
        rdoOpChoices = [ u"+", u"-", u"*", u"/" ]
        self.rdoOp = wx.RadioBox( self.m_panel6, wx.ID_ANY, u"연산자 선택", wx.DefaultPosition, wx.DefaultSize, rdoOpChoices, 1, wx.RA_SPECIFY_ROWS )
        self.rdoOp.SetSelection( 0 )
        bSizer8.Add( self.rdoOp, 1, wx.ALL, 5 )
        
        
        self.m_panel6.SetSizer( bSizer8 )
        self.m_panel6.Layout()
        bSizer8.Fit( self.m_panel6 )
        bSizer5.Add( self.m_panel6, 0, wx.EXPAND |wx.ALL, 5 )
        
        self.m_panel7 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer9 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.m_staticText7 = wx.StaticText( self.m_panel7, wx.ID_ANY, u"연산결과:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText7.Wrap( -1 )
        bSizer9.Add( self.m_staticText7, 0, wx.ALL, 5 )
        
        self.staResult = wx.StaticText( self.m_panel7, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.staResult.Wrap( -1 )
        bSizer9.Add( self.staResult, 0, wx.ALL, 5 )
        
        
        self.m_panel7.SetSizer( bSizer9 )
        self.m_panel7.Layout()
        bSizer9.Fit( self.m_panel7 )
        bSizer5.Add( self.m_panel7, 0, wx.EXPAND |wx.ALL, 5 )
        
        self.m_panel8 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer10 = wx.BoxSizer( wx.HORIZONTAL )
        
        self.btnCalc = wx.Button( self.m_panel8, wx.ID_ANY, u"계산", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer10.Add( self.btnCalc, 0, wx.ALL, 5 )
        
        self.btnClear = wx.Button( self.m_panel8, wx.ID_ANY, u"초기화", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer10.Add( self.btnClear, 0, wx.ALL, 5 )
        
        self.btnExit = wx.Button( self.m_panel8, wx.ID_ANY, u"종료", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer10.Add( self.btnExit, 0, wx.ALL, 5 )
        
        
        self.m_panel8.SetSizer( bSizer10 )
        self.m_panel8.Layout()
        bSizer10.Fit( self.m_panel8 )
        bSizer5.Add( self.m_panel8, 0, wx.EXPAND |wx.ALL, 5 )
        
        
        self.SetSizer( bSizer5 )
        self.Layout()
        
        self.Centre( wx.BOTH )
        
        # Connect Events
        self.btnCalc.id = 1
        self.btnClear.id = 2
        self.btnExit.id = 3
        self.btnCalc.Bind( wx.EVT_BUTTON, self.OnCalcProcess )
        self.btnClear.Bind( wx.EVT_BUTTON, self.OnCalcProcess )
        self.btnExit.Bind( wx.EVT_BUTTON, self.OnCalcProcess )
    
    def __del__( self ): #소멸자
        pass
    
    # Virtual event handlers, overide them in your derived class
    def OnCalcProcess( self, event ):
        sel_id = event.GetEventObject().id
        #print(sel_id)
        
        if sel_id == 1:
            op = self.rdoOp.GetStringSelection()
            #print(op)
            num1 = self.txtNum1.GetValue()
            num2 = self.txtNum2.GetValue()
            
            if num1 == '' or num2 == '':
                wx.MessageBox('값을 입력하시오', '알림', wx.OK)
                return
            
            try:
                result = eval(num1 + op + num2)
            except Exception as e:
                wx.MessageBox('연산오류'+str(e), '알림', wx.OK)
                
            self.staResult.SetLabel(str(result))   
        
        elif sel_id == 2:
            self.txtNum1.SetLabel('')
            self.txtNum2.SetLabel('')
            self.staResult.SetLabel('')
            self.rdoOp.SetSelection(0)
            self.txtNum1.SetFocus() #UX/UI:사용자 편의
        
        elif sel_id == 3: 
            dlg = wx.MessageDialog(self, '정말 종료할까요?','알림', wx.YES_NO) 
            imsi = dlg.ShowModal()
            if imsi ==wx.ID_YES:
                dlg.Destroy() #MessageDialog닫기
                self.Close() #Frame 닫기
  
                
if __name__ == '__main__':
    app = wx.App()
    MyFrame2(None).Show()
    app.MainLoop()   

실행결과

'Python' 카테고리의 다른 글

14. 소켓(Socket)  (0) 2021.05.01
13. 원격(remote) db연동 – MariaDB  (0) 2021.04.29
11. 예외처리  (0) 2021.04.29
10. 내장함수  (0) 2021.04.29
8. 사용자 입력과 출력  (0) 2021.04.29

관련글 더보기