Chapter 23. 메뉴

IT 지식 / Python·2026.08.26
TKINTER GUIDE
Chapter 23. 메뉴
Tkinter에서 메뉴와 툴바를 만드는 방법을 알아봅니다.

23.1 메뉴(Menu)란?

메뉴(Menu)는 프로그램의 기능을 목록 형태로 제공하는 GUI 구성 요소입니다. 사용자는 메뉴를 클릭하여 원하는 기능을 실행할 수 있습니다.

대표적인 메뉴는 다음과 같습니다.

  • 파일(File)
  • 편집(Edit)
  • 보기(View)
  • 도움말(Help)

메뉴는 거의 모든 데스크톱 프로그램에서 사용되며, 예를 들어 다음과 같은 프로그램에서 메뉴를 쉽게 볼 수 있습니다.

  • 메모장
  • 그림판
  • 계산기
  • 회원관리 프로그램
  • 게시판 프로그램

메뉴 예: 파일 편집 보기 도움말

────────────────────────

Tkinter 메뉴 구성은 다음과 같은 구조로 만듭니다.

Menu
│
├── 파일
│      ├── 새로 만들기
│      ├── 열기
│      ├── 저장
│      └── 종료
│
├── 편집
│      ├── 복사
│      ├── 잘라내기
│      ├── 붙여넣기
│
└── 도움말
       └── 프로그램 정보
    
23.2 Menu

Tkinter에서는 Menu 클래스를 이용하여 메뉴를 만듭니다.

Menu 생성
import tkinter as tk  # tkinter 모듈 임포트

window = tk.Tk()  # 창 생성

menu = tk.Menu(window)  # 메뉴 생성

window.config(menu=menu)  # 메뉴 설정

window.mainloop()  # 이벤트 루프 시작

실행하면 빈 메뉴가 생성됩니다.

파일 메뉴 만들기는 다음과 같이 합니다.

파일 메뉴 만들기
file_menu = tk.Menu(  # 파일 메뉴 생성
    menu,  # 부모 메뉴 지정
    tearoff=0  # 분리선 제거
)

menu.add_cascade(  # 메뉴 항목 추가
    label="파일",  # 항목 레이블
    menu=file_menu  # 서브 메뉴 지정
)

tearoff=0은 점선 메뉴를 제거합니다.

메뉴 항목 추가는 다음과 같이 합니다.

메뉴 항목 추가
file_menu.add_command(  # 새로 만들기 명령 추가
    label="새로 만들기"  # 항목 레이블
)

file_menu.add_command(  # 열기 명령 추가
    label="열기"  # 항목 레이블
)

file_menu.add_command(  # 저장 명령 추가
    label="저장"  # 항목 레이블
)

구분선 추가는 다음과 같이 합니다.

구분선 추가
file_menu.add_separator()  # 구분선 추가

실행 화면은 다음과 같습니다.

종료 메뉴는 다음과 같이 추가합니다.

종료 메뉴
file_menu.add_command(  # 종료 명령 추가
    label="종료",  # 항목 레이블
    command=window.destroy  # 종료 명령 설정
)

메뉴 클릭 이벤트는 다음과 같이 설정합니다.

메뉴 클릭 이벤트
import tkinter as tk  # tkinter 모듈 임포트

def hello():  # hello 함수 정의
    print("메뉴 선택")  # 메시지 출력

window = tk.Tk()  # 창 생성

menu = tk.Menu(window)  # 메뉴 생성

window.config(menu=menu)  # 메뉴 설정

file = tk.Menu(menu, tearoff=0)  # 파일 메뉴 생성

menu.add_cascade(label="파일", menu=file)  # 메뉴 항목 추가

file.add_command(  # 새로 만들기 명령 추가
    label="새로 만들기",  # 항목 레이블
    command=hello  # 함수 연결
)

window.mainloop()  # 이벤트 루프 시작

메뉴를 클릭하면 "메뉴 선택"이 출력됩니다.

23.3 Toolbar

Toolbar는 자주 사용하는 기능을 버튼 형태로 모아 놓은 영역입니다. 메뉴보다 빠르게 기능을 실행할 수 있어 실무 프로그램에서 많이 사용됩니다.

Toolbar 예: [새로] [열기] [저장] [삭제]

────────────────────────────

Toolbar 만들기는 다음과 같이 합니다.

Toolbar 만들기
toolbar = tk.Frame(  # 툴바 프레임 생성
    window,  # 부모 창 지정
    bd=1,  # 테두리 두께
    relief="raised"  # 테두리 스타일
)

toolbar.pack(  # 툴바 배치
    side="top",  # 상단에 배치
    fill="x"  # 가로로 채우기
)

버튼 추가는 다음과 같이 합니다.

버튼 추가
tk.Button(  # 등록 버튼 생성
    toolbar,  # 툴바에 추가
    text="등록"  # 버튼 텍스트
).pack(side="left")  # 왼쪽에 배치

tk.Button(  # 조회 버튼 생성
    toolbar,  # 툴바에 추가
    text="조회"  # 버튼 텍스트
).pack(side="left")  # 왼쪽에 배치

tk.Button(  # 삭제 버튼 생성
    toolbar,  # 툴바에 추가
    text="삭제"  # 버튼 텍스트
).pack(side="left")  # 왼쪽에 배치

실행 화면은 다음과 같습니다.

[등록] [조회] [삭제]

회원관리 Toolbar는 다음과 같이 만들 수 있습니다.

회원관리 Toolbar
toolbar = tk.Frame(window)  # 툴바 프레임 생성

toolbar.pack(fill="x")  # 툴바 배치

tk.Button(toolbar, text="등록").pack(side="left")  # 등록 버튼

tk.Button(toolbar, text="수정").pack(side="left")  # 수정 버튼

tk.Button(toolbar, text="삭제").pack(side="left")  # 삭제 버튼

tk.Button(toolbar, text="종료").pack(side="right")  # 종료 버튼
23.4 단축키(Shortcut)

단축키는 키보드만으로 프로그램 기능을 실행하는 기능입니다.

대표적인 단축키는 다음과 같습니다.

단축키 기능
Ctrl + N 새로 만들기
Ctrl + O 열기
Ctrl + S 저장
Ctrl + X 잘라내기
Ctrl + C 복사
Ctrl + V 붙여넣기

bind()를 사용하여 단축키를 등록합니다.

Ctrl + S
import tkinter as tk  # tkinter 모듈 임포트

def save(event):  # 저장 함수 정의
    print("저장")  # 메시지 출력

window = tk.Tk()  # 창 생성

window.bind(  # 키 이벤트 바인딩
    "<Control-s>",  # Ctrl+S 키
    save  # 저장 함수 연결
)

window.mainloop()  # 이벤트 루프 시작

Ctrl + S를 누르면 "저장"이 출력됩니다.

Ctrl + N과 ESC, F1 단축키도 다음과 같이 등록할 수 있습니다.

단축키 등록 예
window.bind(  # 키 이벤트 바인딩
    "<Control-n>",  # Ctrl+N 키
    newFile  # 새 파일 함수 연결
)

window.bind(  # 키 이벤트 바인딩
    "<Escape>",  # Esc 키
    exitProgram  # 종료 함수 연결
)

window.bind(  # 키 이벤트 바인딩
    "<F1>",  # F1 키
    helpProgram  # 도움말 함수 연결
)

메뉴에 단축키 표시를 추가하려면 다음과 같이 합니다.

메뉴에 단축키 표시
file.add_command(  # 저장 명령 추가
    label="저장",  # 항목 레이블
    accelerator="Ctrl+S"  # 단축키 설정
)

accelerator는 메뉴에 단축키를 표시하는 역할만 하며, 실제 동작은 bind()로 등록해야 합니다.

23.5 회원관리 프로그램
회원관리 프로그램 예제
from tkinter import *  # tkinter 기본 위젯 불러오기
from tkinter import filedialog, messagebox  # 파일 대화상자, 알림창 불러오기


def register():  # 등록 버튼 클릭 시 실행
    emp_id = entry_id.get().strip()  # 사번 입력값 가져오기
    name = entry_name.get().strip()  # 이름 입력값 가져오기
    phone = entry_phone.get().strip()  # 전화번호 입력값 가져오기
    address = entry_address.get().strip()  # 주소 입력값 가져오기

    if not emp_id and not name and not phone and not address:  # 모두 비어 있으면
        return  # 등록하지 않고 종료

    text_area.insert(  # 텍스트 영역에 회원 정보 추가
        END,
        f"사번: {emp_id}  이름: {name}  전화번호: {phone}  주소: {address}\n",
    )

    entry_id.delete(0, END)  # 사번 입력란 비우기
    entry_name.delete(0, END)  # 이름 입력란 비우기
    entry_phone.delete(0, END)  # 전화번호 입력란 비우기
    entry_address.delete(0, END)  # 주소 입력란 비우기
    entry_id.focus()  # 사번 입력란에 커서 두기


def new_file(event=None):  # 새로 만들기 (Ctrl+N)
    text_area.delete("1.0", END)  # 텍스트 영역 내용 지우기
    entry_id.delete(0, END)  # 사번 입력란 비우기
    entry_name.delete(0, END)  # 이름 입력란 비우기
    entry_phone.delete(0, END)  # 전화번호 입력란 비우기
    entry_address.delete(0, END)  # 주소 입력란 비우기
    entry_id.focus()  # 사번 입력란에 커서 두기
    return "break"  # 기본 단축키 동작과 중복 방지


def open_file(event=None):  # 파일 열기 (Ctrl+O)
    path = filedialog.askopenfilename(  # 열기 대화상자 표시
        title="열기",
        filetypes=[("텍스트 파일", "*.txt"), ("모든 파일", "*.*")],
    )
    if path:  # 파일을 선택했으면
        with open(path, encoding="utf-8") as f:  # UTF-8로 파일 열기
            text_area.delete("1.0", END)  # 기존 내용 지우기
            text_area.insert("1.0", f.read())  # 파일 내용 넣기
    return "break"  # 기본 단축키 동작과 중복 방지


def save_file(event=None):  # 파일 저장 (Ctrl+S)
    path = filedialog.asksaveasfilename(  # 저장 대화상자 표시
        title="저장",
        defaultextension=".txt",
        filetypes=[("텍스트 파일", "*.txt"), ("모든 파일", "*.*")],
    )
    if path:  # 저장 경로를 선택했으면
        with open(path, "w", encoding="utf-8") as f:  # UTF-8로 파일 쓰기
            f.write(text_area.get("1.0", "end-1c"))  # 텍스트 영역 내용 저장
    return "break"  # 기본 단축키 동작과 중복 방지


def _focused_widget():  # 현재 포커스된 위젯 반환
    return window.focus_get()  # 커서가 있는 위젯 가져오기


def copy_text(event=None):  # 복사 (Ctrl+C)
    widget = _focused_widget()  # 현재 선택된 위젯
    try:
        if isinstance(widget, Text):  # 텍스트 영역이면
            selected = widget.get("sel.first", "sel.last")  # 선택한 글자 가져오기
        elif isinstance(widget, Entry):  # 입력란이면
            selected = widget.selection_get()  # 선택한 글자 가져오기
        else:
            return  # 해당 없으면 종료
        window.clipboard_clear()  # 클립보드 비우기
        window.clipboard_append(selected)  # 선택한 글자를 클립보드에 넣기
    except TclError:  # 선택한 글자가 없으면
        pass  # 무시
    return "break"  # 기본 단축키 동작과 중복 방지


def cut_text(event=None):  # 잘라내기 (Ctrl+X)
    widget = _focused_widget()  # 현재 선택된 위젯
    try:
        if isinstance(widget, Text):  # 텍스트 영역이면
            selected = widget.get("sel.first", "sel.last")  # 선택한 글자 가져오기
            widget.delete("sel.first", "sel.last")  # 선택한 글자 삭제
        elif isinstance(widget, Entry):  # 입력란이면
            selected = widget.selection_get()  # 선택한 글자 가져오기
            widget.delete("sel.first", "sel.last")  # 선택한 글자 삭제
        else:
            return  # 해당 없으면 종료
        window.clipboard_clear()  # 클립보드 비우기
        window.clipboard_append(selected)  # 선택한 글자를 클립보드에 넣기
    except TclError:  # 선택한 글자가 없으면
        pass  # 무시
    return "break"  # 기본 단축키 동작과 중복 방지


def paste_text(event=None):  # 붙여넣기 (Ctrl+V)
    widget = _focused_widget()  # 현재 선택된 위젯
    try:
        clip = window.clipboard_get()  # 클립보드 내용 가져오기
        if isinstance(widget, Text):  # 텍스트 영역이면
            try:
                widget.delete("sel.first", "sel.last")  # 선택한 글자 있으면 지우기
            except TclError:
                pass  # 선택이 없으면 무시
            widget.insert("insert", clip)  # 커서 위치에 붙여넣기
        elif isinstance(widget, Entry):  # 입력란이면
            try:
                widget.delete("sel.first", "sel.last")  # 선택한 글자 있으면 지우기
            except TclError:
                pass  # 선택이 없으면 무시
            widget.insert(INSERT, clip)  # 커서 위치에 붙여넣기
    except TclError:  # 클립보드가 비어 있으면
        pass  # 무시
    return "break"  # 기본 단축키 동작과 중복 방지


def show_info():  # 프로그램 정보 표시
    messagebox.showinfo("프로그램 정보", "회원관리 프로그램입니다.")  # 알림창 띄우기


window = Tk()  # 메인 창 생성
window.title("회원관리 프로그램")  # 창 제목 설정
window.geometry("480x460")  # 창 크기 설정
window.resizable(False, False)  # 창 크기 조절 잠금

menubar = Menu(window)  # 메뉴바 생성

file_menu = Menu(menubar, tearoff=0)  # 파일 메뉴 (분리 방지)
file_menu.add_command(label="새로 만들기", command=new_file, accelerator="Ctrl+N")  # 새로 만들기
file_menu.add_command(label="열기", command=open_file, accelerator="Ctrl+O")  # 열기
file_menu.add_command(label="저장", command=save_file, accelerator="Ctrl+S")  # 저장
file_menu.add_separator()  # 구분선
file_menu.add_command(label="종료", command=window.destroy)  # 종료
menubar.add_cascade(label="파일", menu=file_menu)  # 상단에 파일 메뉴 붙이기

edit_menu = Menu(menubar, tearoff=0)  # 편집 메뉴 (분리 방지)
edit_menu.add_command(label="복사", command=copy_text, accelerator="Ctrl+C")  # 복사
edit_menu.add_command(label="잘라내기", command=cut_text, accelerator="Ctrl+X")  # 잘라내기
edit_menu.add_command(label="붙여넣기", command=paste_text, accelerator="Ctrl+V")  # 붙여넣기
menubar.add_cascade(label="편집", menu=edit_menu)  # 상단에 편집 메뉴 붙이기

help_menu = Menu(menubar, tearoff=0)  # 도움말 메뉴 (분리 방지)
help_menu.add_command(label="프로그램 정보", command=show_info)  # 프로그램 정보
menubar.add_cascade(label="도움말", menu=help_menu)  # 상단에 도움말 메뉴 붙이기

window.config(menu=menubar)  # 창에 메뉴바 연결

window.bind_all("<Control-n>", new_file)  # Ctrl+N → 새로 만들기
window.bind_all("<Control-o>", open_file)  # Ctrl+O → 열기
window.bind_all("<Control-s>", save_file)  # Ctrl+S → 저장
window.bind_all("<Control-x>", cut_text)  # Ctrl+X → 잘라내기
window.bind_all("<Control-c>", copy_text)  # Ctrl+C → 복사
window.bind_all("<Control-v>", paste_text)  # Ctrl+V → 붙여넣기

Label(window, text="회원관리 프로그램", font=("맑은 고딕", 18, "bold")).pack(pady=16)  # 제목 레이블

form = Frame(window)  # 입력 폼을 담을 프레임
form.pack()  # 프레임 배치

Label(form, text="사번:", font=("맑은 고딕", 11)).grid(  # 사번 레이블
    row=0, column=0, sticky=E, padx=8, pady=6
)
entry_id = Entry(form, width=30, font=("맑은 고딕", 11))  # 사번 입력란
entry_id.grid(row=0, column=1, padx=8, pady=6)  # 사번 입력란 배치

Label(form, text="이름:", font=("맑은 고딕", 11)).grid(  # 이름 레이블
    row=1, column=0, sticky=E, padx=8, pady=6
)
entry_name = Entry(form, width=30, font=("맑은 고딕", 11))  # 이름 입력란
entry_name.grid(row=1, column=1, padx=8, pady=6)  # 이름 입력란 배치

Label(form, text="전화번호:", font=("맑은 고딕", 11)).grid(  # 전화번호 레이블
    row=2, column=0, sticky=E, padx=8, pady=6
)
entry_phone = Entry(form, width=30, font=("맑은 고딕", 11))  # 전화번호 입력란
entry_phone.grid(row=2, column=1, padx=8, pady=6)  # 전화번호 입력란 배치

Label(form, text="주소:", font=("맑은 고딕", 11)).grid(  # 주소 레이블
    row=3, column=0, sticky=E, padx=8, pady=6
)
entry_address = Entry(form, width=30, font=("맑은 고딕", 11))  # 주소 입력란
entry_address.grid(row=3, column=1, padx=8, pady=6)  # 주소 입력란 배치

buttons = Frame(window)  # 버튼을 담을 프레임
buttons.pack(pady=16)  # 버튼 프레임 배치

Button(buttons, text="등록", width=10, font=("맑은 고딕", 10), command=register).pack(  # 등록 버튼
    side=LEFT, padx=8
)
Button(  # 종료 버튼
    buttons, text="종료", width=10, font=("맑은 고딕", 10), command=window.destroy
).pack(side=LEFT, padx=8)

text_frame = Frame(window)  # 텍스트 영역과 스크롤바를 담을 프레임
text_frame.pack(padx=16, pady=(0, 16), fill=BOTH, expand=True)  # 아래쪽을 채우며 배치

scrollbar = Scrollbar(text_frame)  # 세로 스크롤바 생성
scrollbar.pack(side=RIGHT, fill=Y)  # 오른쪽에 스크롤바 배치

text_area = Text(  # 회원 목록을 보여줄 텍스트 영역
    text_frame,
    width=52,
    height=10,
    font=("맑은 고딕", 10),
    yscrollcommand=scrollbar.set,  # 텍스트 스크롤과 스크롤바 연결
)
text_area.pack(side=LEFT, fill=BOTH, expand=True)  # 텍스트 영역 배치
scrollbar.config(command=text_area.yview)  # 스크롤바 동작 연결

entry_id.focus()  # 시작 시 사번 입력란에 커서
window.mainloop()  # 창 실행 (이벤트 대기)

📌 Chapter 23 핵심 정리
  • 메뉴는 프로그램의 기능을 목록 형태로 제공하는 GUI 구성 요소이다.
  • Tkinter에서 Menu 클래스를 이용하여 메뉴를 만든다.
  • Toolbar는 자주 사용하는 기능을 버튼 형태로 모아 놓은 영역이다.
  • 단축키는 키보드만으로 프로그램 기능을 실행하는 기능이다.
  • bind()를 사용하여 단축키를 등록할 수 있다.

프로그램·홈페이지·강의가 필요하신가요?

프로그램 판매, 무료 다운로드, 홈페이지 제작, IT 강의 상담을 도와드립니다.

상담 신청하기