[Python] 19. [GUI] wxPython 그래픽 사용자 인터페이스, 다양한 Widget, Menu

2017. 8. 2. 18:33·빅데이터 프로그래밍/Python
728x90
반응형

01. 다양한 Widget

1 wx.MenuBar, wx.Menu, wx.MenuItem 위젯을 통한 메뉴의 출력

- wx.MenuBar: 화면 상/하단위 메뉴바
- wx.Menu: 메뉴바에 붙이는 메뉴 그룹 한 열
- wx.MenuItem: 메뉴열에 붙이는 하나의 메뉴 항목

- wx.MenuBar(): 메뉴들의 구성
- fileNewMenu = fileMenu.Append(wx.ID_ANY, "새 파일"): 메뉴 항목 추가
- fileMenu.AppendSeparator(): 메뉴 구분자
- self.menuBar.Append(fileMenu, "&File"): 메뉴바에 메뉴 붙이기  
- self.Bind(wx.EVT_MENU, self.OnNew, fileNewMenu): 이벤트 등록 

▷ /wxexam/Menu.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Menu Example")
            
        self.menuBar = wx.MenuBar()
        fileMenu = wx.Menu()
        fileNewMenu = fileMenu.Append(wx.ID_ANY, "새 파일")
        fileOpenMenu = fileMenu.Append(wx.ID_ANY, "열기")
        fileMenu.AppendSeparator()  # 구분자
        fileExitMenu = fileMenu.Append(wx.ID_ANY, "끝내기")

        customMenu = wx.Menu()
        customHelloMenu = customMenu.Append(wx.ID_ANY, "&Hello", )
        
        self.menuBar.Append(fileMenu, "&File")   # 메뉴바에 메뉴 붙이기
        self.menuBar.Append(customMenu, "&Test") # 메뉴바에 메뉴 붙이기
        
        self.SetMenuBar(self.menuBar) # 메뉴바를 윈도우에 붙이기

        # 이벤트 등록(이벤트 종류, 핸들러 함수, men 항목)
        self.Bind(wx.EVT_MENU, self.OnNew, fileNewMenu) 
        self.Bind(wx.EVT_MENU, self.OnOpen, fileOpenMenu)
        self.Bind(wx.EVT_MENU, self.OnExit, fileExitMenu)        
        self.Bind(wx.EVT_MENU, self.OnHello, customHelloMenu)
    
    def OnNew(self, e):
        wx.MessageBox("OnNew() Clicked!") # [OK] 버튼 옵션

    def OnOpen(self, e):
        wx.MessageBox("OnOpen() Clicked!")

    def OnExit(self, e):
        self.Close()  # 현재 화면 끝내기 

    def OnHello(self, e):
        wx.MessageBox("Hello.");

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    

-------------------------------------------------------------------------------------

 

2. wx.StaticText, wx.TextCtrl
- wx.StaticText: 문자열 출력
- wx.TextCtrl: 문자열 입력/ 출력 지원

▷ /wxexam/TextCtrl.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="TextCtrl Example")
        self.SetSize(500, 300)
        self.mainPanel = wx.Panel(self)
        
        self.staticRed = wx.StaticText(self.mainPanel, label="Red : ")
        self.textRed = wx.TextCtrl(self.mainPanel, value='255')
        
        self.staticGreen = wx.StaticText(self.mainPanel, label="Green : ")
        self.textGreen = wx.TextCtrl(self.mainPanel, value='255')
        
        self.staticBlue = wx.StaticText(self.mainPanel, label="Blue : ")
        self.textBlue = wx.TextCtrl(self.mainPanel, value='255')
        
        self.gridSizer = wx.GridSizer(rows=3, cols=2, hgap=5, vgap=5)
        self.gridSizer.Add(self.staticRed)
        self.gridSizer.Add(self.textRed, 0, wx.EXPAND)
        self.gridSizer.Add(self.staticGreen)
        self.gridSizer.Add(self.textGreen, 0, wx.EXPAND)
        self.gridSizer.Add(self.staticBlue)
        self.gridSizer.Add(self.textBlue, 0, wx.EXPAND)

        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)
        self.vtBoxSizer.Add(self.gridSizer, 1, wx.EXPAND|wx.ALL, 10)
        self.mainPanel.SetSizer(self.vtBoxSizer)

        self.Bind(wx.EVT_TEXT, self.OnTextChange, self.textRed)
        self.Bind(wx.EVT_TEXT, self.OnTextChange, self.textGreen)
        self.Bind(wx.EVT_TEXT, self.OnTextChange, self.textBlue)
        self.ChangeColor()

    def OnTextChange(self, e):
        self.ChangeColor();

    def ChangeColor(self):
        r = int(self.textRed.GetValue()) # TextCtrl에서 문자열로 값 산출
        g = int(self.textGreen.GetValue())
        b = int(self.textBlue.GetValue())
        self.mainPanel.SetBackgroundColour(wx.Colour(r, g, b))
        self.mainPanel.Refresh()  # 적용

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()


-------------------------------------------------------------------------------------
 
3. wx.RadioButton
- Radio 버튼
- StaticBox는 Panel과 비슷하지만 상단에 Label을 출력
- wx.RadioButton(self.mainBox, label="Red", style=wx.RB_GROUP): 그룹의 시작 선언
▷ /wxexam/RadioButton.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="RadioButton Example")
        self.SetSize(500, 300)
        self.mainPanel = wx.Panel(self)
        self.mainBox = wx.StaticBox(self.mainPanel, label="색깔 지정하기")

        # style=wx.RB_GROUP: 새로운 그룹의 시작
        self.rdoRed     = wx.RadioButton(self.mainBox, label="Red", style=wx.RB_GROUP)
        self.rdoGreen   = wx.RadioButton(self.mainBox, label="Green")
        self.rdoBlue    = wx.RadioButton(self.mainBox, label="Blue")
        
        self.rdoEnable  = wx.RadioButton(self.mainBox, label="Enable", style=wx.RB_GROUP)
        self.rdoDisable = wx.RadioButton(self.mainBox, label="Disable")
        
        self.gridSizer = wx.GridSizer(rows=2, cols=3, hgap=5, vgap=15)
        self.gridSizer.Add(self.rdoRed)
        self.gridSizer.Add(self.rdoGreen)
        self.gridSizer.Add(self.rdoBlue)
        self.gridSizer.Add(self.rdoEnable)
        self.gridSizer.Add(self.rdoDisable)

        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)
        self.vtBoxSizer.Add(self.gridSizer, 1, wx.EXPAND|wx.ALL, 15)
        self.mainBox.SetSizer(self.vtBoxSizer)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.mainBox, 1, wx.EXPAND|wx.ALL, 5)
        self.mainPanel.SetSizer(self.mainSizer)

        self.Bind(wx.EVT_RADIOBUTTON, self.OnRed, self.rdoRed)
        self.Bind(wx.EVT_RADIOBUTTON, self.OnGreen, self.rdoGreen)
        self.Bind(wx.EVT_RADIOBUTTON, self.OnBlue, self.rdoBlue)
        self.Bind(wx.EVT_RADIOBUTTON, self.OnEnable, self.rdoEnable)
        self.Bind(wx.EVT_RADIOBUTTON, self.OnDisable, self.rdoDisable)

    def OnRed(self, e):
        self.mainBox.SetBackgroundColour(wx.Colour(255, 0, 0))
        self.mainBox.Refresh()

    def OnGreen(self, e):
        self.mainBox.SetBackgroundColour(wx.Colour(0, 255, 0))
        self.mainBox.Refresh()

    def OnBlue(self, e):
        self.mainBox.SetBackgroundColour(wx.Colour(0, 0, 255))
        self.mainBox.Refresh()

    def OnEnable(self, e):
        self.rdoRed.Enable(True)  # 활성화
        self.rdoGreen.Enable(True)
        self.rdoBlue.Enable(True)

    def OnDisable(self, e):
        self.rdoRed.Enable(False)  # 비활성화
        self.rdoGreen.Enable(False)
        self.rdoBlue.Enable(False)
        

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    
-------------------------------------------------------------------------------------
 

4. wx.CheckBox
- self.checkBold.SetValue(wx.CHK_CHECKED): 체크 상태 설정
- self.checkItalic.SetValue(wx.CHK_UNCHECKED): 체크하지 않는 상태 설정
-self.vtBoxSizer.Add(self.checkBold, 1, wx.ALL, 5): wx.ALL 명령은 모든면에 border 값을 지정하는 것이나 좌측 정렬 효과도 있음.
- https://wxpython.org/Phoenix/docs/html/search.html?q=CommandEvent

▷ /wxexam/CheckBox.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="CheckBox Example")
        self.SetSize(500, 300)
        self.mainPanel = wx.Panel(self)
        
        self.checkBold = wx.CheckBox(self.mainPanel, label="Bold")
        self.checkBold.SetValue(wx.CHK_CHECKED) # 체크 설정

        self.checkItalic = wx.CheckBox(self.mainPanel, label="Italic")
        self.checkItalic.SetValue(wx.CHK_UNCHECKED) # 체크 미설정
        
        self.staticText = wx.StaticText(self.mainPanel, label="I am a Programmer.")        

        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)
        self.vtBoxSizer.Add(self.checkBold, 1, wx.ALL, 5)
        self.vtBoxSizer.Add(self.checkItalic, 1, wx.ALL, 5)
        self.vtBoxSizer.Add(self.staticText, 1, wx.EXPAND | wx.ALL, 5)
        self.mainPanel.SetSizer(self.vtBoxSizer)

        self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.checkBold)
        self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.checkItalic)
        self.ChangeFont() # 초기 설정

    def OnCheck(self, evt):
        print('type(evt): ' + str(type(evt)))
        print('type(evt.GetString()): ' + str(evt.GetString()))
        print('type(evt.GetSelection()): ' + str(evt.GetSelection()))
        print('type(evt.IsChecked()): ' + str(evt.IsChecked()))
        print('type(evt.Selection): ' + str(evt.Selection))
        self.ChangeFont()

    def ChangeFont(self):
        style = wx.FONTSTYLE_NORMAL
        weight = wx.FONTWEIGHT_NORMAL

        if self.checkBold.GetValue() == wx.CHK_CHECKED:
            weight = wx.FONTWEIGHT_BOLD
        if self.checkItalic.GetValue() == wx.CHK_CHECKED:
            style = wx.FONTSTYLE_ITALIC

        font = wx.Font(30, wx.FONTFAMILY_DEFAULT, style, weight)
        self.staticText.SetFont(font)

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    


-------------------------------------------------------------------------------------
 
5. wx.ListBox, wx.ComboBox
- self.colorCombo = wx.ComboBox(self.mainPanel, choices=colors, style=wx.CB_READONLY): Panel, 선택값, 편집 기능 해제
▷ /wxexam/ListCombo.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Combo/ListBox Example")
        self.SetSize(420, 250)
        self.mainPanel = wx.Panel(self)
        
        colors = ["Red", "Orange", "Yellow", "Green", "Blue"]
        self.colorCombo = wx.ComboBox(self.mainPanel, choices=colors, style=wx.CB_READONLY, size=wx.Size(100, 200))
        
        self.colorListBox = wx.ListBox(self.mainPanel, size=wx.Size(100, 200))
        
        self.hzBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.hzBoxSizer.Add(self.colorCombo, 0, wx.ALL, 5) # 콤보 박스
        self.hzBoxSizer.Add(self.colorListBox, 0, wx.ALL, 5) # 리스트 박스
        self.mainPanel.SetSizer(self.hzBoxSizer)

        # 이벤트 등록
        self.Bind(wx.EVT_COMBOBOX, self.OnComboBox, self.colorCombo)
        self.Bind(wx.EVT_LISTBOX, self.OnListBox, self.colorListBox)

    def OnComboBox(self, e):
        idx = self.colorCombo.GetCurrentSelection() # 선택된 index 0
        print('idx: ' + str(idx))
        print('self.colorCombo.Items[idx]: ' + self.colorCombo.Items[idx])
        self.colorListBox.Append(self.colorCombo.Items[idx])

    def OnListBox(self, e):
        idx = self.colorListBox.GetSelection()
        # self.colorCombo.Append("List 클릭 발생")
        wx.MessageBox(self.colorListBox.Items[idx]) # [OK]

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
     

-------------------------------------------------------------------------------------
 
6. wx.TreeCtrl
- 메뉴의 출력
- root = self.tree.AddRoot('태조'): 최초 메뉴 등록
- self.tree.AppendItem(root, '방우'): 메뉴 등록
- taejong = self.tree.AppendItem(root, '태종(방원)'): 하위 메뉴 구성
- self.tree.AppendItem(taejong, '양녕'): 새로운 하위 메뉴에 메뉴 등록

▷ /wxexam/TreeCtrl.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="TreeCtrl Example")
        self.SetSize(420, 320)
        self.mainPanel = wx.Panel(self)
        self.expandButton = wx.Button(self.mainPanel, label="Expand")        

        self.tree = wx.TreeCtrl(self.mainPanel)
        root = self.tree.AddRoot('태조')
        self.tree.AppendItem(root, '방우')
        self.tree.AppendItem(root, '정종(방과)')
        self.tree.AppendItem(root, '방의')
        self.tree.AppendItem(root, '방간')
        taejong = self.tree.AppendItem(root, '태종(방원)')
        self.tree.AppendItem(root, '방연')

        self.tree.AppendItem(taejong, '양녕')
        self.tree.AppendItem(taejong, '효령')
        self.tree.AppendItem(taejong, '세종(충녕)')
        self.tree.AppendItem(taejong, '효령')

        self.staticText = wx.StaticText(self.mainPanel, style=wx.ALIGN_CENTER)
                    
        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)    
            
        self.vtBoxSizer.Add(self.expandButton, 0, wx.EXPAND|wx.ALL, 5)
        self.vtBoxSizer.Add(self.tree, 1, wx.EXPAND|wx.ALL, 5)
        self.vtBoxSizer.Add(self.staticText, 0, wx.EXPAND|wx.ALL, 5)
        
        self.mainPanel.SetSizer(self.vtBoxSizer)

        self.Bind(wx.EVT_BUTTON, self.OnExpandButton, self.expandButton)
        
        # 트리 노드 클릭시
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnNodeSelected, self.tree)

    def OnExpandButton(self, e):
        self.tree.ExpandAll()  # 트리메뉴 전부 펼침

    def OnNodeSelected(self, e):
        selected = self.tree.GetSelection() # 0 ~
        self.staticText.SetLabel(self.tree.GetItemText(selected))
        self.mainPanel.Layout() # staticText 위젯의 크기 변경되어 다시 Layout 적용
        
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    

-------------------------------------------------------------------------------------
 
7. wx.Slider, wx.Gauge
- wx.Slider: 볼륨등 사용자의 입출력 처리
- wx.Gauge: 연료의 상태등 출력
▷ /wxexam/SliderGuage.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Slider & Gauge")
        self.SetSize(500, 120)
        self.mainPanel = wx.Panel(self)

        self.slider = wx.Slider(self.mainPanel, minValue=0, maxValue=100)
        self.gauge = wx.Gauge(self.mainPanel, range=200)        
                    
        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)        
        self.vtBoxSizer.Add(self.slider, 0, wx.EXPAND|wx.ALL, 5)
        self.vtBoxSizer.Add(self.gauge, 0, wx.EXPAND|wx.ALL, 5)
        self.mainPanel.SetSizer(self.vtBoxSizer)
        
        # 이벤트 등록
        self.Bind(wx.EVT_SLIDER, self.OnSliderChange, self.slider)

    def OnSliderChange(self, e):
        self.gauge.SetValue(self.slider.GetValue())
                
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    
-------------------------------------------------------------------------------------
 
8. wx.Dialog
- dlg.ShowModal(): dialog를 닫기전에 부모창을 이용할 수 없음.
- dlg.Show(): dialog를 닫기전에 부모창을 이용할 수 있음.      
▷ /wxexam/Dialog.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

import wx

class MyDialog(wx.Dialog):
    # _parent: 부모 Frame, _title: 창 제목
    def __init__(self, _parent, _title):
        wx.Dialog.__init__(self, parent=_parent, title=_title)
        self.SetSize(300, 150)
        self.mainPanel = wx.Panel(self)        
        self.closeButton = wx.Button(self.mainPanel, label="Close")

        self.vtBoxSizer = wx.BoxSizer(wx.VERTICAL)        
        self.vtBoxSizer.Add(self.closeButton, 0, wx.ALIGN_CENTER|wx.ALL, 40)
        self.mainPanel.SetSizer(self.vtBoxSizer)

        self.Bind(wx.EVT_BUTTON, self.OnClose, self.closeButton)
        self.Bind(wx.EVT_CLOSE, self.OnClose) # Dialog 에 이벤트 등록

    def OnClose(self, e):        
        self.Destroy()
        
class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Modal & Modeless")
        self.SetSize(500, 300)
        self.mainPanel = wx.Panel(self)

        self.modalButton = wx.Button(self.mainPanel, label="Modal")
        self.ModelessButton = wx.Button(self.mainPanel, label="Modeless")
                     
        self.fgridSizer = wx.FlexGridSizer(rows=1, cols=2, hgap=5, vgap=5) 
        
        self.fgridSizer.Add(self.modalButton, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        self.fgridSizer.Add(self.ModelessButton, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
        
        self.fgridSizer.AddGrowableCol(1) # 화면 크기에따라 두번째 컬럼 반영
        self.mainPanel.SetSizer(self.fgridSizer)

        self.Bind(wx.EVT_BUTTON, self.OnModalButton, self.modalButton)
        self.Bind(wx.EVT_BUTTON, self.OnModelessButton, self.ModelessButton)

    def OnModalButton(self, e):
        dlg = MyDialog(self, "Modal Dialog")
        dlg.ShowModal()

    def OnModelessButton(self, e):
        dlg = MyDialog(self, "Modeless Dialog")
        dlg.Show()        

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()

    app.MainLoop()
    
    
-------------------------------------------------------------------------------------
 

728x90
반응형

'빅데이터 프로그래밍 > Python' 카테고리의 다른 글

[Python] 21. [DBMS] Sqlite3 + Python 연동 실습  (0) 2017.08.05
[Python] 20. [DBMS] 데이터베이스 개론, SQLite3 사용  (0) 2017.08.02
[Python] 18. [GUI] wxPython 그래픽 사용자 인터페이스, 기본 Widget, Sizer  (0) 2017.08.02
[Python] 17. [Network] threading module, 채팅 서버/클라이언트 제작  (0) 2017.08.02
[Python] 16. [Network] socketserver 네트워크 프레임워크, Echo Server 2, 파일 송수신  (0) 2017.08.02
'빅데이터 프로그래밍/Python' 카테고리의 다른 글
  • [Python] 21. [DBMS] Sqlite3 + Python 연동 실습
  • [Python] 20. [DBMS] 데이터베이스 개론, SQLite3 사용
  • [Python] 18. [GUI] wxPython 그래픽 사용자 인터페이스, 기본 Widget, Sizer
  • [Python] 17. [Network] threading module, 채팅 서버/클라이언트 제작
밍글링글링
밍글링글링
mingling - 밍글링, 밍글밍글링. 코드와 어우러지다. IT/ 프로그래밍/소스
    반응형
    250x250
  • 밍글링글링
    mingling
    밍글링글링
  • 전체
    오늘
    어제
    • 밍글링글링 (407) N
      • Flutter (2)
      • 일상생활 (8)
        • 리뷰 (1)
        • 생활정보 (4)
        • 맛집 (0)
        • 여행 (0)
        • 모든정보 (3)
      • JAVA (126)
        • 개념 (6)
        • 예제 (115)
        • Exception (2)
      • C (1)
        • C (1)
        • C++ (0)
        • C# (0)
      • JS (29)
        • JavaScript (18)
        • JQuery (5)
        • AJax (0)
        • NODE.JS (6)
        • Angular.JS 2.0 (0)
      • WEB (87)
        • HTML (6)
        • CSS (61)
        • JSP (20)
        • JSTL (0)
      • FrameWork (8)
        • Spring (8)
        • BootStrap (0)
        • MyBATIS (0)
        • JUnit (0)
      • 외부 라이브러리 (5)
      • 공유 소스 관리 (5)
        • Git (5)
        • SVN (0)
      • 빅데이터 프로그래밍 (37)
        • Python (37)
        • R Programming (0)
      • DB (7)
        • ORACLE (0)
        • MySql (6)
      • Development Tools (7)
        • StarUML (0)
        • eXERD (0)
        • Eclipse (4)
      • SKILL (6)
        • Migration (0)
        • Security (6)
      • MicroSoft (0)
        • Excel (0)
        • Word (0)
      • Android (0)
      • Server (21)
        • Ubuntu (5)
        • Linux (15)
      • IOS (0)
      • XML (0)
      • 미디어 (0)
      • 공지사항 (3)
      • NETWORK (1)
      • 게임 (4)
        • 피파 (1)
        • 리니지M (0)
        • 배틀그라운드 (1)
        • 듀랑고 (2)
      • 세상 이슈 (6)
      • 일렉트론 (0)
      • 대회 소식 (4)
      • 업무 (2)
      • Express, Vue (6)
      • docker (11)
      • svelte (3)
      • 블록체인 (1)
      • IT (10) N
      • Rust (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    jsp include
    API 설계
    리눅스 설치
    vscode
    오류
    css float
    자바 for문
    자바 클래스
    proxy pass
    css transition
    SSL 인증서
    css table
    gitlab 설치
    에디터 팁
    css perspective
    React Compiler
    nginx ssl 설정
    vue 설치
    svelte
    css tb
    css list
    러스트
    클론코딩
    Node
    VS Code 팁
    mysql db
    프런트엔드
    티스토리 자동화
    Java Array
    ssl 인증서 발급
    자바 배열
    spring java
    servlet class
    자바 생성자
    vue cli
    rust linux
    AI 코딩 에이전트
    nginx
    Extension Bisect
    Rust lang
    lang rust
    nginx ssl 적용
    자바 객체 지향
    java casting
    css block
    자바 exception
    docker
    브라우저 자동화
    jsp parameter
    ubuntu
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
밍글링글링
[Python] 19. [GUI] wxPython 그래픽 사용자 인터페이스, 다양한 Widget, Menu
상단으로

티스토리툴바