목차
가장 중요한 메뉴의 특징에 대해 요약해보자.
- 클래식한 메뉴는 실제로 어플리 케이션 창의 맨 위에 위치한 수평 막대이다.
- 막대에는 항목이라하는 수평으로 배치된 여러 옵션들을 포함한다.
- 이러한 옵션에는 사용자가 마우스를 사용하지 않고도 작업에 액세스 할 수 있도록 키보드 단축키(핫키. hot-keys) 가 있을 수 있다.
- 메뉴의 옵션을 단축키던 마우스던 선택하면 두가지 효과 중 하나가 발생한다.
- 옵션에 바인딩된 콜백을 싲가한다.
- 새로운 메뉴(하위 메뉴)가 펼쳐진다.
- tkinter 애플리케이션에서 메뉴를 만들고 싶다면 다음을 수행해야한다.
- 최상위 메뉴 객체를 생성한다.
- 창안에 삽입한다.
- 여러개의 필수 하위메뉴를 바인딩(cascade)하거나 단일 콜백을 연결한다.
실습 1 ) 메인 창에 메뉴 만들기
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
root = tk.Tk()
# 메인 메뉴 생성 및 창에 넣기
main_menu = tk.Menu(root)
root.config(menu=main_menu)
#첫번째 메뉴 추가
file_menu = tk.Menu(main_menu)
main_menu.add_cascade(label="File", menu=file_menu)
#두번째 메뉴 추가 : 콜백 추가
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app)
root.mainloop()
이 메뉴는 현재 하위 메뉴가 존재하지 않고 상단에 File , Help의 상위 메뉴들로 만 구성되어 있다.
그리고, 마우스없이 사용하기 어렵다는 점이 있다.
다른 기능들과 세부적인 메뉴가 필요하다.
실습 2 ) 단축키 추가
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu)
main_menu.add_cascade(label="File", menu=file_menu, underline=0) # 단축키 추가
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1) # 단축키 추가
root.mainloop()
underline=0 은 Alt + F 와 같고 underline=1은 Alt +B와 같다.
모든 단축키가 고유해야하고, 겹치는 요소들이 없어야 한다.
실습 3 ) 하위 메뉴 구성
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure(): #나가기 콜백 함수
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure) # command 콜백 함수 추가
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
하위 메뉴 상단에 이상한 점섬을 확인했을 것이다.
이 점선은 티어오프(tearoff)라고 하는데, 아주 오래전 GUI에서 사용되던 고풍스런 스타일로, 현재는 선호되지 않는다.
이에 대해 tearoff=0을 추가하여 차이점을 확인해보자.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure():
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0) # tearoff 삭제
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure)
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
그리고, 새로운 기능을 하나 더 추가하여 Open이라는 메뉴를 file아래로 추가해보자.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure():
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
def open_file(): # 콜백 함수 추가
massagebox.showinfo("Open doc", "Opening file...")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Open..", underline=0, command=open_file) # 하위 메뉴 추가 및 콜백 함수 적용
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure)
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
Open..과 Quit 사이의 선이 있었으면 좋겠다면, add_separator()를 적용해보자.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure():
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
def open_file():
massagebox.showinfo("Open doc", "Opening file...")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Open..", underline=0, command=open_file)
file_menu.add_separator() # 구분선 추가
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure)
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
실습 4 ) 하위 메뉴 구성하기
하위 메뉴를 계단식으로 펼쳐야 하는 경우 add_cascade()를 활용하여 추가할 수 있다.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure():
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
def open_file():
massagebox.showinfo("Open doc", "Opening file...")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Open..", underline=0, command=open_file)
sub_file_menu = tk.Menu(file_menu, tearoff=0) #하위 메뉴 구성
file_menu.add_cascade(label="Sub File", menu=sub_file_menu, underline=5) # 해당하는 메뉴에 add_cascade를 통해 하위 메뉴 참조
file_menu.add_separator()
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure)
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
물론 현재 sub_file_menu에는 add 된 부분이 없어, 화살표만 생성되어있음을 볼 수 있다.
그렇기 때문에 하위 sub_file_menu에 add_command를 통해 label을 추가해보자.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure():
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
def open_file():
massagebox.showinfo("Open doc", "Opening file...")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Open..", underline=0, command=open_file)
sub_file_menu = tk.Menu(file_menu, tearoff=0)
file_menu.add_cascade(label="Sub File", menu=sub_file_menu, underline=5)
for i in range(1, 8):
sub_file_menu.add_command(label=f"{str(i)}. Sub File.txt", underline=0) # for 문을 통한 1.Sub File.txt 의 형식으로 생성
file_menu.add_separator()
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure)
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.mainloop()
실습 5 ) Hot - keys 적용
일부 메뉴에 전용 단축키를 통해 접근할 수 있도록 하기 위해 두 단계를 수행해야한다.
- hot-keys의 이름을 지정하는 문자열을 accelerator 속성에 설정한다.
항목 내부에 오른쪽에 정렬된 문자열을 표시하는 것 외 다른 효과는 없고 콜백은 설정되지 않는다. - 핫키와 적절한 콜백을 연결하는 global binding을 한다.
import tkinter as tk
from tkinter import messagebox
def help_app():
messagebox.showinfo("App","The application\nthat does nothing")
def are_you_sure(event=None): #bind() 하기 위한 인자 설정
if messagebox.askyesno("Quit", "Are you sure you want to quit?"):
root.destroy()
def open_file():
massagebox.showinfo("Open doc", "Opening file...")
root = tk.Tk()
main_menu = tk.Menu(root)
root.config(menu=main_menu)
file_menu = tk.Menu(main_menu, tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu, underline=0)
file_menu.add_commnad(label="Open..", underline=0, command=open_file)
sub_file_menu = tk.Menu(file_menu, tearoff=0)
file_menu.add_cascade(label="Sub File", menu=sub_file_menu, underline=5)
for i in range(1, 8):
sub_file_menu.add_command(label=f"{str(i)}. Sub File.txt", underline=0)
file_menu.add_separator()
file_menu.add_commnad(label="Quit", underline=0, command=are_you_sure, accelerator="Ctrl-Q") # accelerator 문구 지정
help_menu = tk.Menu(main_menu)
main_menu.add_command(label="Help", command=help_app, underline=1)
root.bind_all("<Control-q>", are_you_sure) # are_you_sure 에 대한 콜백 함수를 <Control-q> 이벤트로 바인드.
root.mainloop()
참고 사항
하위 메뉴 항목을 config()를 통해 수정할 수 없다.
tkinter의 관점에서 해당 항목은 위젯이 아니라 특정 위젯의 구성요소 일 뿐이기 때문이다.
메뉴 항목을 조작하기 위해서는 전용 메서드를 사용해야한다.
menu_object.entryconfigure(i, prop=value)
- i : 수정된 항목의 정수 인덱스이다.
- prop = value : 수정된 속성을 가르키는 키워드 인수이다.
import tkinter as tk
def on_off():
global accessible
if accessible == tk.DISABLED:
accessible = tk.ACTIVE
else:
accessible = tk.DISABLED
sub_menu.entryconfigure(1, state=accessible)
accessible = tk.DISABLED
root = tk.Tk()
menu = tk.Menu(root)
root.config(menu=menu)
sub_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Menu", menu=sub_menu)
sub_menu.add_command(label="On/Off", command=on_off)
sub_menu.add_command(lable="Switch", state=tk.DISABLED)
root.mainloop()
해당 entryconfigure()함수를 통해 인덱스 1 번에 해당하는 switch의 요소가 선택되어,
On/Off를 선택할때마다 Switch의 버튼의 활성화 상태값이 변화하는 것을 볼 수 있다.
'Developer > Python' 카테고리의 다른 글
[python] GUI programming tkInter (Canvas) (0) | 2025.07.10 |
---|---|
[python] GUI programming tkInter (메인창 구성 및 messagebox) (6) | 2025.07.10 |
[python] GUI programming tkInter (클릭 불가능 위젯) (0) | 2025.07.08 |
[python] GUI programming tkInter (클릭 가능 위젯) (4) | 2025.07.08 |
[python] GUI programming tkInter (위젯 속성과 메서드) (0) | 2025.07.07 |