본문 바로가기
Programming/Python

wxPython 기본 위젯 - 003 - Panel, Sizer, Menu, Status Bar

by The Programmer 2026. 9. 7.

1. Introduction

 

코드만 우선 올려둡니다. Panel과 Sizer에 대한 충분한 학습 및 연습이 우선되어야. Menu와 Status Bar는 그렇게 어렵지 않은 것으로. ^.^;

 

 

2. Code

 

2.1 Panel Basic

 

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="wx.Panel 구조 이해 - 5개 버튼", size=(800, 500))

        # -------------------------------------------------
        # 1) Frame 바로 아래의 좌우 패널 2개
        # -------------------------------------------------
        self.leftPanel = wx.Panel(self)
        self.rightPanel = wx.Panel(self)

        self.leftPanel.SetBackgroundColour(wx.Colour(220, 235, 245))
        self.rightPanel.SetBackgroundColour(wx.Colour(235, 235, 235))

        # -------------------------------------------------
        # 2) 왼쪽 패널 버튼 및 레이아웃 (추가된 부분)
        # -------------------------------------------------
        self.btnLeft = wx.Button(self.leftPanel, label="Left", size=(120, 24))

        # 왼쪽 패널도 자체 sizer를 가짐
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        # leftSizer.AddStretchSpacer(1)    # 상단 여백용 스페이서
        leftSizer.Add(self.btnLeft, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        leftSizer.AddStretchSpacer(1)
        self.leftPanel.SetSizer(leftSizer)

        # -------------------------------------------------
        # 3) 오른쪽 패널 안의 세로 4개 서브패널
        # -------------------------------------------------
        self.subPanel1 = wx.Panel(self.rightPanel)
        self.subPanel2 = wx.Panel(self.rightPanel)
        self.subPanel3 = wx.Panel(self.rightPanel)
        self.subPanel4 = wx.Panel(self.rightPanel)

        self.subPanel1.SetBackgroundColour(wx.Colour(255, 220, 220))
        self.subPanel2.SetBackgroundColour(wx.Colour(220, 255, 220))
        self.subPanel3.SetBackgroundColour(wx.Colour(220, 220, 255))
        self.subPanel4.SetBackgroundColour(wx.Colour(255, 245, 210))

        # 버튼 생성
        self.btn1 = wx.Button(self.subPanel1, label="1", size=(120, 24))
        self.btn2 = wx.Button(self.subPanel2, label="2", size=(120, 24))
        self.btn3 = wx.Button(self.subPanel3, label="3", size=(120, 24))
        self.btn4 = wx.Button(self.subPanel4, label="4", size=(120, 24))

        # -------------------------------------------------
        # 4) 각 서브패널 내부 레이아웃
        # -------------------------------------------------
        for panel, button in [
            (self.subPanel1, self.btn1),
            (self.subPanel2, self.btn2),
            (self.subPanel3, self.btn3),
            (self.subPanel4, self.btn4),
        ]:
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.AddStretchSpacer(1)
            sizer.Add(button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
            sizer.AddStretchSpacer(1)
            panel.SetSizer(sizer)

       # -------------------------------------------------
        # 5) 오른쪽 패널 내부의 4개 패널 배치
        # -------------------------------------------------
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer.Add(self.subPanel1, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel2, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel3, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel4, 1, wx.EXPAND | wx.ALL, 2)
        self.rightPanel.SetSizer(rightSizer)

        # -------------------------------------------------
        # 6) Frame 내부의 좌우 패널 배치
        # -------------------------------------------------
        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(self.leftPanel, 1, wx.EXPAND | wx.ALL, 4)
        mainSizer.Add(self.rightPanel, 2, wx.EXPAND | wx.ALL, 4)
        self.SetSizer(mainSizer)

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

"""
버튼을 상단으로 재정렬하기 :

# 기존 코드에서 상단 스페이서만 제거
leftSizer = wx.BoxSizer(wx.VERTICAL)

# [삭제] leftSizer.AddStretchSpacer(1) 

leftSizer.Add(self.btnLeft, 0, wx.ALIGN_CENTER | wx.ALL, 5) # 가로 중앙 정렬 유지
leftSizer.AddStretchSpacer(1) # 하단 스페이서가 공간을 확보해 버튼을 상단에 고정
self.leftPanel.SetSizer(leftSizer)

"""

 

 

 

2.2 Menu and Status Bar

 

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="wx.Panel 구조 이해 - 메뉴/상태바 추가", size=(800, 500))

        # -------------------------------------------------
        # 0) Frame의 메뉴바와 상태바 추가
        # -------------------------------------------------
        menuBar = wx.MenuBar()
        fileMenu = wx.Menu()
        fileMenu.Append(wx.ID_EXIT, "종료")
        menuBar.Append(fileMenu, "파일")
        self.SetMenuBar(menuBar)

        self.CreateStatusBar()
        self.SetStatusText("준비됨")

        # -------------------------------------------------
        # 1) Frame 바로 아래의 좌우 패널 2개
        # -------------------------------------------------
        self.leftPanel = wx.Panel(self)
        self.rightPanel = wx.Panel(self)

        self.leftPanel.SetBackgroundColour(wx.Colour(220, 235, 245))
        self.rightPanel.SetBackgroundColour(wx.Colour(235, 235, 235))

        # -------------------------------------------------
        # 2) 왼쪽 패널 버튼 및 레이아웃
        # -------------------------------------------------
        self.btnLeft = wx.Button(self.leftPanel, label="Left", size=(120, 24))

        leftSizer = wx.BoxSizer(wx.VERTICAL)
        leftSizer.Add(self.btnLeft, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        leftSizer.AddStretchSpacer(1)
        self.leftPanel.SetSizer(leftSizer)

        # -------------------------------------------------
        # 3) 오른쪽 패널 안의 세로 4개 서브패널
        # -------------------------------------------------
        self.subPanel1 = wx.Panel(self.rightPanel)
        self.subPanel2 = wx.Panel(self.rightPanel)
        self.subPanel3 = wx.Panel(self.rightPanel)
        self.subPanel4 = wx.Panel(self.rightPanel)

        self.subPanel1.SetBackgroundColour(wx.Colour(255, 220, 220))
        self.subPanel2.SetBackgroundColour(wx.Colour(220, 255, 220))
        self.subPanel3.SetBackgroundColour(wx.Colour(220, 220, 255))
        self.subPanel4.SetBackgroundColour(wx.Colour(255, 245, 210))

        # -------------------------------------------------
        # 4) 각 서브패널의 버튼
        # -------------------------------------------------
        self.btn1 = wx.Button(self.subPanel1, label="1", size=(120, 24))
        self.btn2 = wx.Button(self.subPanel2, label="2", size=(120, 24))
        self.btn3 = wx.Button(self.subPanel3, label="3", size=(120, 24))
        self.btn4 = wx.Button(self.subPanel4, label="4", size=(120, 24))

        # -------------------------------------------------
        # 5) 각 서브패널 내부 레이아웃
        # -------------------------------------------------
        for panel, button in [
            (self.subPanel1, self.btn1),
            (self.subPanel2, self.btn2),
            (self.subPanel3, self.btn3),
            (self.subPanel4, self.btn4),
        ]:
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.AddStretchSpacer(1)
            sizer.Add(button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
            sizer.AddStretchSpacer(1)
            panel.SetSizer(sizer)

        # -------------------------------------------------
        # 6) 오른쪽 패널 내부의 4개 패널 배치
        # -------------------------------------------------
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer.Add(self.subPanel1, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel2, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel3, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel4, 1, wx.EXPAND | wx.ALL, 2)
        self.rightPanel.SetSizer(rightSizer)

        # -------------------------------------------------
        # 7) Frame 내부의 좌우 패널 배치
        # -------------------------------------------------
        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(self.leftPanel, 1, wx.EXPAND | wx.ALL, 4)
        mainSizer.Add(self.rightPanel, 2, wx.EXPAND | wx.ALL, 4)
        self.SetSizer(mainSizer)

        # -------------------------------------------------
        # 8) 메뉴 이벤트 연결
        # -------------------------------------------------
        self.Bind(wx.EVT_MENU, self.on_exit, id=wx.ID_EXIT)

    def on_exit(self, event):
        self.Close()


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

 

 

 

2.1 Extended

 

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="wx.Panel 구조 이해 - 메뉴/상태바 추가", size=(800, 500))

        # -------------------------------------------------
        # 0) Frame의 메뉴바와 상태바 추가
        # -------------------------------------------------
        menuBar = wx.MenuBar()

        fileMenu = wx.Menu()
        fileMenu.Append(wx.ID_NEW, "New")
        fileMenu.Append(wx.ID_OPEN, "Open")
        fileMenu.AppendSeparator()
        fileMenu.Append(wx.ID_SAVE, "Save")
        fileMenu.Append(wx.ID_SAVEAS, "Save As")
        fileMenu.AppendSeparator()
        fileMenu.Append(wx.ID_EXIT, "Exit")

        editMenu = wx.Menu()
        editMenu.Append(wx.ID_UNDO, "Undo")
        editMenu.Append(wx.ID_REDO, "Redo")
        editMenu.AppendSeparator()
        editMenu.Append(wx.ID_CUT, "Cut")
        editMenu.Append(wx.ID_COPY, "Copy")
        editMenu.Append(wx.ID_PASTE, "Paste")
        editMenu.Append(wx.ID_SELECTALL, "Select All")

        optionsMenu = wx.Menu()
        optionsMenu.Append(wx.ID_ANY, "Font")
        optionsMenu.Append(wx.ID_ANY, "Extra Settings")

        windowsMenu = wx.Menu()
        windowsMenu.Append(wx.ID_ANY, "Cascade")
        windowsMenu.Append(wx.ID_ANY, "Tile")

        helpMenu = wx.Menu()
        helpMenu.Append(wx.ID_ABOUT, "About")

        menuBar.Append(fileMenu, "File")
        menuBar.Append(editMenu, "Edit")
        menuBar.Append(optionsMenu, "Options")
        menuBar.Append(windowsMenu, "Windows")
        menuBar.Append(helpMenu, "Help")
        self.SetMenuBar(menuBar)

        self.CreateStatusBar()
        self.SetStatusText("준비됨")

        # -------------------------------------------------
        # 1) Frame 바로 아래의 좌우 패널 2개
        # -------------------------------------------------
        self.leftPanel = wx.Panel(self)
        self.rightPanel = wx.Panel(self)

        self.leftPanel.SetBackgroundColour(wx.Colour(220, 235, 245))
        self.rightPanel.SetBackgroundColour(wx.Colour(235, 235, 235))

        # -------------------------------------------------
        # 2) 왼쪽 패널 버튼 및 레이아웃
        # -------------------------------------------------
        self.btnLeft = wx.Button(self.leftPanel, label="Left", size=(120, 24))

        leftSizer = wx.BoxSizer(wx.VERTICAL)
        leftSizer.Add(self.btnLeft, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        leftSizer.AddStretchSpacer(1)
        self.leftPanel.SetSizer(leftSizer)

        # -------------------------------------------------
        # 3) 오른쪽 패널 안의 세로 4개 서브패널
        # -------------------------------------------------
        self.subPanel1 = wx.Panel(self.rightPanel)
        self.subPanel2 = wx.Panel(self.rightPanel)
        self.subPanel3 = wx.Panel(self.rightPanel)
        self.subPanel4 = wx.Panel(self.rightPanel)

        self.subPanel1.SetBackgroundColour(wx.Colour(255, 220, 220))
        self.subPanel2.SetBackgroundColour(wx.Colour(220, 255, 220))
        self.subPanel3.SetBackgroundColour(wx.Colour(220, 220, 255))
        self.subPanel4.SetBackgroundColour(wx.Colour(255, 245, 210))

        # -------------------------------------------------
        # 4) 각 서브패널의 버튼
        # -------------------------------------------------
        self.btn1 = wx.Button(self.subPanel1, label="1", size=(120, 24))
        self.btn2 = wx.Button(self.subPanel2, label="2", size=(120, 24))
        self.btn3 = wx.Button(self.subPanel3, label="3", size=(120, 24))
        self.btn4 = wx.Button(self.subPanel4, label="4", size=(120, 24))

        # -------------------------------------------------
        # 5) 각 서브패널 내부 레이아웃
        # -------------------------------------------------
        for panel, button in [
            (self.subPanel1, self.btn1),
            (self.subPanel2, self.btn2),
            (self.subPanel3, self.btn3),
            (self.subPanel4, self.btn4),
        ]:
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.AddStretchSpacer(1)
            sizer.Add(button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
            sizer.AddStretchSpacer(1)
            panel.SetSizer(sizer)

        # -------------------------------------------------
        # 6) 오른쪽 패널 내부의 4개 패널 배치
        # -------------------------------------------------
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer.Add(self.subPanel1, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel2, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel3, 1, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.subPanel4, 1, wx.EXPAND | wx.ALL, 2)
        self.rightPanel.SetSizer(rightSizer)

        # -------------------------------------------------
        # 7) Frame 내부의 좌우 패널 배치
        # -------------------------------------------------
        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(self.leftPanel, 1, wx.EXPAND | wx.ALL, 4)
        mainSizer.Add(self.rightPanel, 2, wx.EXPAND | wx.ALL, 4)
        self.SetSizer(mainSizer)

        # -------------------------------------------------
        # 8) 메뉴 이벤트 연결
        # -------------------------------------------------
        self.Bind(wx.EVT_MENU, self.on_exit, id=wx.ID_EXIT)
        self.Bind(wx.EVT_MENU, self.on_about, id=wx.ID_ABOUT)

    def on_exit(self, event):
        self.Close()

    def on_about(self, event):
        wx.MessageBox("wxPython 예제", "About", wx.OK | wx.ICON_INFORMATION)


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

 

 

3. Result

 

1) 2.1 Panel Basic :

 

 

2) 2.2 Menu and Status Bar

 

 

3) 2.3 Extended

 

 

4. Notes

 

Not yet! ^.^;

 

Panel and Sizer!

 

 

■ 응용 연습 과제

1) 랜덤 컬러링

2) 좌우 균형 맞추기

 

 

5. Files

 

^.^;

wxPython_Intro_Ex_007_Panel_001_.py
0.00MB
wxPython_Intro_Ex_007_Panel_002_with_MenuBar_n_StatusBar_.py
0.00MB
wxPython_Intro_Ex_007_Panel_003_with_MenuBar_Extended_n_StatusBar_.py
0.01MB

 

 

6. Ref.

 

 

Happy Programming!

^.^;