개요
파일컨트롤(wx.FileCtrl)은 스태틱텍스트(wx.StaticText), 리스트컨트롤(wx.ListCtrl), 텍스트컨트롤(wx.TextCtrl), 그리고 콤보상자(wx.ComboBox)의 조합으로 이루어진 위젯이다. 기본적으로 폴더를 자유롭게 왔다갔다 할 수 있고, 파일을 선택할 수 있다. 예제에서는 파일컨트롤을 이용하여 그림파일을 열고, 또 회전도 시킬 수 있는 팝업메뉴를 구성하였다.
wx.FileCtrl
파일컨트롤은 아래와 같이 선언한다.
fc = wx.FileCtrl(parent, id=ID_ANY, defaultDirectory="",
defaultFilename="", wildCard="All Files(*.*)|*.*",
style=wx.FC_DEFAULT_STYLE, pos=wx.DefaultPosition, size=wx.DefaultSize,
name="")
parent: 부모클래스
id: 아이디
defaultDirectory: 기본디렉토리. 맨 처음 보여주는 폴더. 빈 문자열이면 현재 작업디렉토리를 띄운다. (os.getcwd())
defaultFilename: 기본파일명.
wildcard: 파일컨트롤에 보여질 파일 필터라고 생각하면된다. 와일드카드로 지정된 파일 확장자만 보여진다.
style: 스타일은 wx.FC_DEFAULT_STYLE을 포함하여 파일을 열 때 적합한 wx.FC_OPEN, 저장할 때 적합한 wx.FC_SAVE, 여러 파일을 한 번에 선택할 수 있는 wx.FC_MULTIPLE, 그리고 마지막으로 숨김파일을 보여줄지 체크박스를 별도로 생성하는 wx.FC_NOSHOWHIDDEN이 있다. 이 조건들은 서로 상충되어 같이 사용할 수 없는 것들도 있으니 동시 사용에 주의하자.
pos: 위치 (x,y)
size: 크기 (x,y)
name: 위젯이름
예제
아래 예제는 파일컨트롤에서 PNG 파일을 더블클릭하면 우측 패널에 그림이 뜨는 예제이다. 또 파일 선택 후 마우스 우클릭을 하면 팝업메뉴가 뜨고, 그림을 오른쪽으로 회전시키거나, 왼쪽으로 회전시킬 수 있다. (그 외 다른 메뉴들은 구현하지 않았다.) 파일컨트롤을 이용하여 파일을 여는 법과 함께 그림파일을 다루는 법도 알아보자.
import wx
class Example(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self,parent,id,'Example Window', size=(950,500))
panel = wx.Panel(self, -1)
# 이미지 디스플레이용 패널
self.png_panel = wx.Panel(panel, -1)
self.png_panel.SetBackgroundColour((220,220,220))
self.sbmp = wx.StaticBitmap(self.png_panel, -1)
# 파일컨트롤
fileCtrl = wx.FileCtrl(panel, 321, defaultDirectory="D:/",pos=wx.DefaultPosition, size=(300,-1),
defaultFilename="", wildCard="All Files (*.*)|*.*",
style=wx.FC_DEFAULT_STYLE|wx.FC_MULTIPLE|wx.FC_NOSHOWHIDDEN)
# 초기 기본 디렉토리 설정
fileCtrl.SetDirectory("d:/icon/")
# 박스사이저
bsizer = wx.BoxSizer(wx.HORIZONTAL)
bsizer.Add(fileCtrl, 0, wx.ALL|wx.EXPAND, 20)
bsizer.Add(self.png_panel,1, wx.TOP|wx.BOTTOM|wx.RIGHT|wx.EXPAND, 20)
panel.SetSizer(bsizer)
self.Center()
# 파일 선택시 이벤트
self.Bind(wx.EVT_FILECTRL_SELECTIONCHANGED, self.OnSelectionChanged)
# 파일 우클릭
self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnRightClicked)
# 파일 더블클릭
self.Bind(wx.EVT_FILECTRL_FILEACTIVATED, self.OnDClicked)
# 백스페이스
fileCtrl.Bind(wx.EVT_CHAR_HOOK, self.OnBackSpace)
fileCtrl.SetFocus()
# 파일 더블클릭
def OnDClicked(self,e):
fileCtrl = e.GetEventObject()
# 선택된 파일경로
path = fileCtrl.GetPaths()[0]
# png 파일인 경우,
if path.endswith('.png'):
# 비트맵 생성
bmp = wx.Bitmap(wx.Image(path, type=wx.BITMAP_TYPE_PNG).Scale(300,300))
# 비트맵 레이블 할당
self.sbmp.SetBitmap(bmp)
# 그림 가운데 표시
self.sbmp.Center()
# 파일 선택시 동작
def OnSelectionChanged(self,e):
fileCtrl = e.GetEventObject()
selected_files = fileCtrl.GetFilenames()
# PNG 그림파일 우클릭시 메뉴
def OnRightClicked(self,e):
# 파일컨트롤 객체 반환
fileCtrl = e.GetEventObject().GetParent()
# 파일컨트롤에서 선택된 파일 이름 리스트 반환
fnames = fileCtrl.GetFilenames()
import os
# 파일 확장자 분리
ext = set([os.path.splitext(e)[-1] for e in fnames])
if ext=={'.png'}:
# 마우스 커서 위치 확인
import pyautogui
x,y = pyautogui.position()
# 이벤트 오브젝트 확인
obj = e.GetEventObject()
# 팝업메뉴생성
pop = PopupMenu(self)
self.PopupMenu(pop, (x/2,y/2)) # 모니터 별 스케일팩터는 다름.. (1 또는 2)
pop.Destroy()
# 백스페이스 누르면
def OnBackSpace(self,e):
# 키코드 확인 (숫자값)
key = e.GetKeyCode()
e_obj = e.GetEventObject().GetParent() # 파일컨트롤 객체 반환
# 백스페이스 누르면,
if e_obj.GetName() == 'wxfilectrl' and key==8:
e_obj.SetFocus()
# 뒤로가기
dirpath = e_obj.GetDirectory()
from pathlib import Path
path = Path(dirpath)
# 부모디렉토리 경로 확인
pdir = path.parent.absolute()
# 파일컨트롤 경로 변경 (부모디렉토리)
e_obj.SetDirectory(str(pdir))
else:
# if 조건에 해당안되는 경우 이벤트 스킵
e.Skip()
# 서브메뉴
class SubMenu(wx.Menu):
def __init__(self):
wx.Menu.__init__(self)
# 메뉴아이콘
img_paint = wx.Bitmap(wx.Image("d:/icon/win/paint.png").Scale(16,16))
img_pic = wx.Bitmap(wx.Image("d:/icon/win/pic.png").Scale(16,16))
img_snipping = wx.Bitmap(wx.Image("d:/icon/win/snipping.png").Scale(16, 16))
img_store = wx.Bitmap(wx.Image("d:/icon/win/microsoft.png").Scale(16, 16))
img_others = wx.Bitmap(wx.Image("d:/icon/win/others.png").Scale(16, 16))
# 메뉴아이템
paint = wx.MenuItem(self, 201, "그림판")
pic = wx.MenuItem(self, 202, "사진")
snipping = wx.MenuItem(self, 203, "캡쳐도구")
store = wx.MenuItem(self, 204, "Microsoft Store 검색")
others = wx.MenuItem(self, 205, "다른 앱 검색")
# 아이콘
paint.SetBitmap(img_paint)
pic.SetBitmap(img_pic)
snipping.SetBitmap(img_snipping)
store.SetBitmap(img_store)
others.SetBitmap(img_others)
# 메뉴(wx.Menu)에 등록
self.Append(paint)
self.Append(pic)
self.Append(snipping)
self.Append(store)
self.AppendSeparator() # 구분자
self.Append(others)
# 팝업메뉴
class PopupMenu(wx.Menu):
def __init__(self, frame):
wx.Menu.__init__(self)
self.frame = frame
# 아이콘
img_cut = wx.Bitmap(wx.Image("d:/icon/win/cut.png").Scale(16,16))
img_copy = wx.Bitmap(wx.Image("d:/icon/win/copy.png").Scale(16, 16))
# 메뉴 아이콘
img_open = wx.Bitmap(wx.Image("d:/icon/win/open.png").Scale(16,16))
img_program = wx.Bitmap(wx.Image("d:/icon/win/program.png").Scale(16, 16))
img_setbg = wx.Bitmap(wx.Image("d:/icon/win/background.png").Scale(16, 16))
img_rotater = wx.Bitmap(wx.Image("d:/icon/win/rotate-right.png").Scale(16, 16))
img_rotatel = wx.Bitmap(wx.Image("d:/icon/win/rotate-left.png").Scale(16, 16))
img_zip = wx.Bitmap(wx.Image("d:/icon/win/zip-file.png").Scale(16, 16))
img_copyto = wx.Bitmap(wx.Image("d:/icon/win/copyto.png").Scale(16, 16))
img_pref = wx.Bitmap(wx.Image("d:/icon/win/pref.png").Scale(16, 16))
img_options = wx.Bitmap(wx.Image("d:/icon/win/moreoptions.png").Scale(16, 16))
# 메뉴 아이템 생성
cut = wx.MenuItem(self, wx.ID_CUT, "", "잘라내기\t(Ctrl+X)")
copy = wx.MenuItem(self, wx.ID_COPY, "", "복사\t(Ctrl+C)")
open = wx.MenuItem(self, 101, "열기")
# 서브메뉴 구성
set_bg = wx.MenuItem(self, 103, "바탕 화면 배경으로 설정")
rotate_r = wx.MenuItem(self, 104, "오른쪽으로 회전")
rotate_l = wx.MenuItem(self, 105, "왼쪽으로 회전")
zip = wx.MenuItem(self, 106, "ZIP 파일로 압축")
copy_to = wx.MenuItem(self, 107, "경로로 복사")
preference = wx.MenuItem(self, 108, "속성\tAlt+Enter")
options = wx.MenuItem(self, 109, "더 많은 옵션 표시\t Shift+F10")
# 메뉴에 아이템 연결
self.Append(cut)
self.Append(copy)
self.AppendSeparator() # 구분자
self.Append(open)
program = self.AppendSubMenu(SubMenu(), '연결 프로그램', )
self.Append(set_bg)
self.Append(rotate_r)
self.Append(rotate_l)
self.Append(zip)
self.Append(copy_to)
self.Append(preference)
self.AppendSeparator() # 구분자
self.Append(options)
# 메뉴 아이템에 이미지 연결
cut.SetBitmap(img_cut)
copy.SetBitmap(img_copy)
open.SetBitmap(img_open)
program.SetBitmap(img_program)
set_bg.SetBitmap(img_setbg)
rotate_r.SetBitmap(img_rotater)
rotate_l.SetBitmap(img_rotatel)
zip.SetBitmap(img_zip)
copy_to.SetBitmap(img_copyto)
preference.SetBitmap(img_pref)
options.SetBitmap(img_options)
# 메뉴 아이템 클릭시 이벤트 바인딩
# 코드가 복잡해지니 "회전" 기능을 제외한 다른 메뉴들은 별도로 바인딩 하지 않는다.
self.Bind(wx.EVT_MENU, self.OnRotateL, rotate_l)
self.Bind(wx.EVT_MENU, self.OnRotateR, rotate_r)
# Right 회전
def OnRotateR(self, e):
fileCtrl = wx.FindWindowById(321)
# 선택된 파일경로
path = fileCtrl.GetPaths()[0]
# png 파일인 경우,
if path.endswith('.png'):
# 비트맵 생성
bmp = wx.Bitmap(wx.Image(path, type=wx.BITMAP_TYPE_PNG).Scale(300, 300).Rotate90(clockwise=True))
# 비트맵 레이블 할당
self.frame.sbmp.SetBitmap(bmp)
# 그림 가운데 표시
self.frame.sbmp.Center()
# Left 회전
def OnRotateL(self, e):
fileCtrl = wx.FindWindowById(321)
# 선택된 파일경로
path = fileCtrl.GetPaths()[0]
# png 파일인 경우,
if path.endswith('.png'):
# 비트맵 생성
bmp = wx.Bitmap(wx.Image(path, type=wx.BITMAP_TYPE_PNG).Scale(300, 300).Rotate90(clockwise=False))
# 비트맵 레이블 할당
self.frame.sbmp.SetBitmap(bmp)
# 그림 가운데 표시
self.frame.sbmp.Center()
if __name__=="__main__":
app = wx.App()
frame=Example(parent=None, id=-1)
frame.Show()
app.MainLoop()
도움되셨다면 하트(♥) 부탁드리고, 더 궁금한 사항은 댓글로 남겨주세요 :)
'wxPython' 카테고리의 다른 글
파이썬 GUI, Aui툴바 AuiToolBar (0) | 2023.04.29 |
---|---|
파이썬 GUI, 툴바 wx.ToolBar (0) | 2023.04.22 |
파이썬 GUI, 팝업메뉴 PopupMenu (0) | 2023.03.24 |
파이썬 GUI, 파이비지인포 PyBusyInfo (0) | 2023.03.21 |
파이썬 GUI, 풍선 팁 BalloonTip (0) | 2023.03.21 |