2023.04.22 - [wxPython] - [wxPython] ToolBar - 툴바
개요
지난 번에 wxPython의 툴바(wx.ToolBar)에 대해 알아보았다. 이번에는 그보다 조금 더 세련되고 편리한 AuiToolBar(wx.lib.agw.aui.auibar.AuiToolBar)에 대해 알아본다. 예제에서는 AuiToolBar와 함께 AuiManager를 이용하여 툴바의 위치를 이리저리 바꿀 수 있고, 툴바에 컨트롤(wx.Control)도 넣을 수 있으며, 심지어 창 밖에서 Floating 하는 툴바를 생성하는 것을 만들어본다!
wx.lib.agw.aui.auibar.AuiToolBar
AuiToolBar가 기존 툴바와 다른 점은 겉으로 보이는 GUI모습 외에도 기존 툴바 대비 더욱 다양한 기능을 제공하는 데 있다. 가령, 툴바가 윈도우보다 작을 때 드롭다운 메뉴를 자동 생성하여 밖으로 밀려난 아이템을 보여줄 수 있다.
또 서로 다른 툴바끼리 도킹(Docking)이 되고, 심지어 윈도우 밖으로 플로팅(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()
도움되셨다면 하트(♥) 부탁드리고, 더 궁금한 사항은 댓글로 남겨주세요 :)
'wxPython' 카테고리의 다른 글
파이썬 GUI, Matplotlib 그래프, 차트, 이미지 띄우기 (0) | 2023.05.03 |
---|---|
파이썬 GUI, 로딩시 로고화면 넣기, 스플래시 스크린 Advanced Splash (0) | 2023.04.30 |
파이썬 GUI, 툴바 wx.ToolBar (0) | 2023.04.22 |
파이썬 GUI, 파일컨트롤 wx.FileCtrl (0) | 2023.03.26 |
파이썬 GUI, 팝업메뉴 PopupMenu (0) | 2023.03.24 |