1. Tkinter 위젯
앞 아티클에서 언급했듯이, Tkinter는 제한된(Limited) 핵심 위젯들만을 제공하고 있다. 아래는 Tkinter가 제공하는 주요 위젯들이다.
위젯 | 설명 |
---|---|
Button | 단순한 버튼 |
Label | 텍스트 혹은 이미지 표시 |
CheckButton | 체크박스 |
Entry | 단순한 한 라인 텍스트 박스 |
ListBox | 리스트 박스 |
RadioButton | 옵션 버튼 |
Message | Label과 비슷하게 텍스트 표시. Label과 달리 자동 래핑 기능이 있다. |
Scale | 슬라이스 바 |
Scrollbar | 스크롤 바 |
Text | 멀티 라인 텍스트 박스로서 일부 Rich Text 기능 제공 |
Menu | 메뉴 Pane |
Menubutton | 메뉴 버튼 |
Toplevel | 새 윈도우를 생성할 때 사용. Tk()는 윈도우를 자동으로 생성하지만 추가로 새 윈도우 혹은 다이얼로그를 만들 경우 Toplevel를 사용한다 |
Frame | 컨테이너 위젯. 다른 위젯들을 그룹화할 때 사용 |
Canvas | 그래프와 점들로 그림을 그릴 수 있으며, 커스텀 위젯을 만드는데 사용될 수도 있다 |
2. 위젯 사용
위젯은 객체를 생성하여 필요한 속성들을 지정하여 사용한다. 위젯은 부모 컨테이너와 연관하여 어떤 상대적 위치에 놓이게 되는데, 앞에 설명한 Geometry Manager를 사용하여 각 위젯의 위치를 정하게 된다.
아래 예제는 레이블 안에 이미지를 넣고 화면에 보여주는 코드로서, MyFrame 이라는 클래스를 만들고 생성자에서 필요한 위젯들을 배치하고 있다. 우선 main() 에서는 Tk 객체 root를 만들고 title()을 사용하여 윈도우 제목을 설정하고, geometry()를 사용하여 윈도우의 크기와 좌표를 정해주었다. geometry() 안의 문자열은 윈도우 크기 및 좌표를 "가로x세로+X+Y" 형식으로 표현한다. MyFrame 클래스는 Frame으로부터 상속된 파생클래스이고, 생성자에서 Label 하나를 추가하고 있다. Label은 좌표 (0,0)에 위치(place)하게 되고, 레이블 안에는 이미지를 넣고 있다. 이미지는 tkinter의 PhotoImage 클래스를 사용하고 있는데, 이 클래스는 .gif 파일 (혹은 PGM) 만을 읽을 수 있다. 다른 이미지 포맷을 사용하기 위해서는 외부 모듈을 사용해야 한다. PhotoImage() 에 이미지 파일을 적고 리턴된 객체를 레이블에 지정하면 되는데, 특히 가비지 컬렉션으로부터 삭제되는 것을 방지하기 위해 lbl.image = img 처럼 레퍼런스를 증가시켜 준다.
from tkinter import * class MyFrame(Frame): def __init__(self, master): img = PhotoImage(file='test.gif') lbl = Label(image=img) lbl.image = img # 레퍼런스 추가 lbl.place(x=0, y=0) def main(): root = Tk() root.title('이미지 보기') root.geometry('500x400+10+10') myframe = MyFrame(root) root.mainloop() if __name__ == '__main__': main()
3. 입력 화면 예제
아래 예제는 고객 데이타를 입력 받는 간단한 윈도우 샘플이다. 메인 Frame 안에 4개의 자식 Frame을 사용하였고, 각각의 자식 Frame 안에 레이블, 텍스트, 버튼 등의 위젯들을 추가하였다.
from tkinter import * from tkinter.ttk import * class MyFrame(Frame): def __init__(self, master): Frame.__init__(self, master) self.master = master self.master.title("고객 입력") self.pack(fill=BOTH, expand=True) # 성명 frame1 = Frame(self) frame1.pack(fill=X) lblName = Label(frame1, text="성명", width=10) lblName.pack(side=LEFT, padx=10, pady=10) entryName = Entry(frame1) entryName.pack(fill=X, padx=10, expand=True) # 회사 frame2 = Frame(self) frame2.pack(fill=X) lblComp = Label(frame2, text="회사명", width=10) lblComp.pack(side=LEFT, padx=10, pady=10) entryComp = Entry(frame2) entryComp.pack(fill=X, padx=10, expand=True) # 특징 frame3 = Frame(self) frame3.pack(fill=BOTH, expand=True) lblComment = Label(frame3, text="특징", width=10) lblComment.pack(side=LEFT, anchor=N, padx=10, pady=10) txtComment = Text(frame3) txtComment.pack(fill=X, pady=10, padx=10) # 저장 frame4 = Frame(self) frame4.pack(fill=X) btnSave = Button(frame4, text="저장") btnSave.pack(side=LEFT, padx=10, pady=10) def main(): root = Tk() root.geometry("600x550+100+100") app = MyFrame(root) root.mainloop() if __name__ == '__main__': main()