본문 바로가기

wxPython

파이썬 GUI, Aui툴바 AuiToolBar

반응형

기존 툴바 대비 고급스럽고 기능이 더욱 다양해진 AuiToolBar

2023.04.22 - [wxPython] - [wxPython] ToolBar - 툴바

 

[wxPython] ToolBar - 툴바

개요 툴바(wx.ToolBar)는 메뉴바(wx.MenuBar) 아래에 위치한 여러 개의 버튼으로 이루어진 wxPython 위젯이다. wx.ToolBar 툴바(wx.ToolBar)는 여러 개의 툴베이스(wx.ToolBarToolBase)들로 이루어진다. 툴베이스란 툴

hexa-coding.tistory.com

 

개요 

    지난 번에 wxPython의 툴바(wx.ToolBar)에 대해 알아보았다. 이번에는 그보다 조금 더 세련되고 편리한 AuiToolBar(wx.lib.agw.aui.auibar.AuiToolBar)에 대해 알아본다. 예제에서는 AuiToolBar와 함께 AuiManager를 이용하여 툴바의 위치를 이리저리 바꿀 수 있고, 툴바에 컨트롤(wx.Control)도 넣을 수 있으며, 심지어 창 밖에서 Floating 하는 툴바를 생성하는 것을 만들어본다!

 

 

wx.lib.agw.aui.auibar.AuiToolBar 

    AuiToolBar가 기존 툴바와 다른 점은 겉으로 보이는 GUI모습 외에도 기존 툴바 대비 더욱 다양한 기능을 제공하는 데 있다. 가령, 툴바가 윈도우보다 작을 때 드롭다운 메뉴를 자동 생성하여 밖으로 밀려난 아이템을 보여줄 수 있다. 

AuiToolBar의 자동 드롭다운 기능

또 서로 다른 툴바끼리 도킹(Docking)이 되고, 심지어 윈도우 밖으로 플로팅(Floating)도 가능하다. 

두 개의 툴바가 서로 도킹된 상태
툴바가 플로팅(Floating)중인 상태 (우상단)

    AuiToolBar 기존에 답답했던 툴바(wx.ToolBar)를 확실히 다이나믹하게 바꿔놓은 것 같다.  그래서 개인적으로 AuiManager(wx.lib.agw.aui.framemanager.AuiManager)를 사용하여 이리 저리 움직일 수 있는 AuiToolBar는 정말 매력적이라고 생각한다. 툴바에 엄청난 자유도를 주어 GUI를 보다 생동감있게 변화시킬 수 있기 때문이다! 

    AuiToolBar도 기존 ToolBar와 유사하게 ToolBase들로 이루어진다. (ToolBase는 툴바에 위치한 각 아이콘들이다) 따라서 정의하는 방식도 기존과 크게 다르지 않다. 아래와 같이 AuiToolBar 클래스를 초기화 해주면 된다. 

tb1 = AuiToolBar(parent, id=-1, style=AUI_TB_TEXT,
                 agwStyle=AUI_TB_DEFAULT_STYLE | AUI_TB_OVERFLOW | AUI_TB_GRIPPER)

    parent: (GUI 구조상) 부모 오브젝트

    id: 아이디 

    style: 컨트롤 윈도우의 스타일을 정의 

    agwStyle: agw(Advanced Generic Widget, 고급일반위젯) 윈도우의 스타일을 정의. 말이 조금 어려운데, 그냥 기존 ToolBar에는 없는 AuiToolBar만의 윈도우 스타일이라 생각하면 된다. agwStyle 속성값에는 여러가지가 있는데, 그 중 유용한 기능이 AUI_TB_OVERFLOW이다. 아이템이 프레임을 넘어갈 경우 자동으로 드롭다운 메뉴(위 사진 참조)를 생성시켜준다. AUI_TB_GRIPPER는 툴바 좌측(HORIZONTAL인 경우) 혹은 툴바 상단(VERTICAL인 경우)에 '......'과 같은 핸들을 만들어주고 이부분을 드래그하면 툴바 전체를 이동시킬 수 있게 하는 기능이다. AUI_TB_GRIPPER만 넣는다고 바로 툴바가 드래그 되지는 않고, 반드시 AuiManager와 함께 구현해주어야 한다. 이는 예제에서 확인할 수 있다. 

 

 

예제 

    예제에서는 기본적으로 AuiToolBar를 구성하는 방법을 알아보고, AuiManager를 이용하여 간단히 툴바를 이리저리 움직일 수 있게 자유도를 주었다. 코드가 길어 복잡해보일 수 있으나, 파이참에서 함수부분을 "Collapse" 시켜서 보면 전체 구조를 쉽게 파악할 수 있다.

반응형
from wx.lib.agw.aui.auibar import *
from wx.lib.agw.aui.framemanager import AuiManager, AuiPaneInfo

class Example(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self,parent,id,'Example Window', size=(400,300))

        # 메뉴바 생성
        self.CreateMenuBar()
        # 툴바1 생성
        self.CreateTB1()
        # 툴바2 생성
        self.CreateTB2()
        # AuiManager 생성
        # AuiPaneInfo : 각 Pane의 위치좌표, 상태(도킹, 플로팅, 히든 등), 사이즈, 캡션 등 스크린에서 확인되는 특성정보를 정의하는 클래스
        # 아래의 Layer(0)과 Layer(1)을 빼고서도 실행해보자.
        self._mgr = AuiManager(self)
        # 상단에 위치시키고, 위에서 첫번째 레이어이며, 그냥Pane이 아니라 툴바용 Pane
        self._mgr.AddPane(tb1, AuiPaneInfo().Top().Layer(0).ToolbarPane())
        # 상단에 위치시키고, 위에서 두번째 레이어이며, 그냥Pane이 아니라 툴바용 Pane
        self._mgr.AddPane(tb2, AuiPaneInfo().Top().Layer(1).ToolbarPane())

        # 툴바가 들어갈 박스사이저 생성
        bsizer = wx.BoxSizer(wx.VERTICAL)
        bsizer.Add(tb1, 0, wx.EXPAND)
        bsizer.Add(tb2, 0, wx.EXPAND)

        # 사이저 패널에 셋업 후 프레임 위치 가운데로 조정
        self.SetSizer(bsizer)
        self.Center()

        # AuiManager 업데이트
        self._mgr.Update()


    # 상단 메뉴바 정의
    def CreateMenuBar(self):
        # 메뉴바 생성
        menubar = wx.MenuBar()

        # File 메뉴 버튼과 그 하위 항목
        file_menu = wx.Menu()
        file_menu.Append(wx.ID_ANY, "Open...", '파일 열기')  # 차례로 id / 메뉴항목 / 상태표시줄 텍스트
        file_menu.Append(wx.ID_ANY, "Exit", '프로그램을 종료합니다.')

        # Edit 메뉴 버튼과 그 하위 항목
        edit_menu = wx.Menu()
        edit_menu.Append(wx.ID_ANY, "Undo", '되돌리기')
        edit_menu.Append(wx.ID_ANY, "Redo", '복구')

        # 앞서 정의한 File 메뉴와 Edit 메뉴를 "메뉴바"에 붙인다.
        menubar.Append(file_menu, "File")
        menubar.Append(edit_menu, "Edit")

        # 메뉴바를 "self" (=MenubarExampleFrame)에 세팅하고 사용자에게 보여준다.
        self.SetMenuBar(menubar)

        # 프레임 하단에 상태표시줄을 만든다.
        status = self.CreateStatusBar()

    # 툴바 1 정의
    def CreateTB1(self):
        global tb1
        # 툴바1 객체 생성
        # AUI_TB_DEFAULT_STYLE : 기본스타일 설정
        # AUI_TB_OVERFLOW : 프레임 사이즈가 작아져 툴바 아이콘이 가려지게 될 경우, 별도의 드롭다운 버튼을 생성
        # AUI_TB_GRIPPER : 툴바 좌측에 그리퍼 표시
        tb1 = AuiToolBar(self, id=11, style=AUI_TB_TEXT,
                         agwStyle=AUI_TB_DEFAULT_STYLE | AUI_TB_OVERFLOW | AUI_TB_GRIPPER)

        tb_dict = {'Copy': ['copy.png', '복사'],
                   'Cut': ['scissors.png', '잘라내기'],
                   'Paste': ['paste.png', '붙여넣기'],
                   'Exit': ['logout.png', '종료']}

        # 툴바에 툴버튼 생성
        n_id = 2
        for key, value in tb_dict.items():
            # AddTool 메소드가 인자를 Bitmap으로 받기 때문에 이미지를 Bitmap으로 변환 (wx.Bitmap) 시켜야 한다.
            # 이미지 열기 -> png로 객체생성 -> 스케일조정 -> 비트맵 형식으로 변경의 네 단계이다.
            bmp = wx.Bitmap(
                wx.Image("D:/icon/" + value[0], type=wx.BITMAP_TYPE_PNG).Rescale(25, 25, wx.IMAGE_QUALITY_HIGH))
            # 툴버튼 생성
            toolbase = tb1.AddTool(n_id, key, bmp, wx.NullBitmap, short_help_string=value[1], kind=wx.ITEM_NORMAL)
            n_id += 1

        # 구분자 삽입
        tb1.AddSeparator()

        # RADIO 툴베이스 생성
        # 왼쪽정렬 버튼
        bmp = wx.Bitmap(
            wx.Image("D:/icon/alignleft.png", type=wx.BITMAP_TYPE_PNG).Rescale(20, 20, wx.IMAGE_QUALITY_HIGH))
        radio_a = tb1.AddRadioTool(n_id, "좌측 정렬", bmp, wx.NullBitmap, short_help_string="왼쪽 정렬")
        n_id += 1
        # 가운데 정렬 버튼
        bmp = wx.Bitmap(
            wx.Image("D:/icon/aligncenter.png", type=wx.BITMAP_TYPE_PNG).Rescale(20, 20, wx.IMAGE_QUALITY_HIGH))
        radio_b = tb1.AddRadioTool(n_id, "가운데 정렬", bmp, wx.NullBitmap, short_help_string="가운데 정렬")
        n_id += 1
        # 오른쪽 정렬 버튼
        bmp = wx.Bitmap(
            wx.Image("D:/icon/alignright.png", type=wx.BITMAP_TYPE_PNG).Rescale(20, 20, wx.IMAGE_QUALITY_HIGH))
        radio_c = tb1.AddRadioTool(n_id, "오른쪽 정렬", bmp, wx.NullBitmap, short_help_string="오른쪽 정렬")
        n_id += 1

        # 구분자 삽입
        tb1.AddSeparator()

        # 콤보박스 삽입
        combo = wx.ComboBox(tb1, n_id, "(글꼴)", choices=["맑은고딕", "바탕체", "휴먼옛체", "굴림체", "궁서체"])
        n_id += 1
        tb1.AddControl(combo)

        # 툴베이스 마진 생성 (marginX, marginY)
        tb1.SetMarginsXY(5, 5)
        # 툴바 생성 후 반드시 Realize()를 해줘야 화면에 뜬다.
        tb1.Realize()

    # 툴바 2 정의
    def CreateTB2(self):
        global tb2
        # 툴바1 객체 생성
        # AUI_TB_DEFAULT_STYLE : 기본스타일 설정
        # AUI_TB_OVERFLOW : 프레임 사이즈가 작아져 툴바 아이콘이 가려지게 될 경우, 별도의 드롭다운 버튼을 생성
        # AUI_TB_GRIPPER : 툴바 좌측에 그리퍼 표시

        tb2 = AuiToolBar(self, id=12, style=AUI_TB_TEXT,
                         agwStyle=AUI_TB_DEFAULT_STYLE | AUI_TB_OVERFLOW | AUI_TB_GRIPPER)


        tb_dict = {'Instagram': ['insta.png', '인스타그램'],
                   'Color': ['color.png', '색상선택'],
                   'Call': ['call.png', '전화'],
                   'Question': ['question.png', '질문사항']}

        # 툴바에 툴버튼 생성
        n_id = 22
        for key, value in tb_dict.items():
            # AddTool 메소드가 인자를 Bitmap으로 받기 때문에 이미지를 Bitmap으로 변환 (wx.Bitmap) 시켜야 한다.
            # 이미지 열기 -> png로 객체생성 -> 스케일조정 -> 비트맵 형식으로 변경의 네 단계이다.
            bmp = wx.Bitmap(wx.Image("D:/icon/" + value[0], type=wx.BITMAP_TYPE_PNG).Rescale(25, 25, wx.IMAGE_QUALITY_HIGH))
            # 툴버튼 생성
            toolbase = tb2.AddTool(n_id, key, bmp, wx.NullBitmap, short_help_string=value[1], kind=wx.ITEM_NORMAL)
            n_id += 1

        # 구분자 삽입
        tb2.AddSeparator()

        # 툴베이스 마진 생성 (marginX, marginY)
        tb2.SetMarginsXY(5, 5)
        # 툴바 생성 후 반드시 Realize()를 해줘야 화면에 뜬다.
        tb2.Realize()
        

if __name__=="__main__":
    app = wx.App()
    frame=Example(parent=None, id=1)
    frame.Show()
    app.MainLoop()

 

 

 

 

 

    도움되셨다면 하트(♥) 부탁드리고, 더 궁금한 사항은 댓글로 남겨주세요 :) 

 

 

 

반응형