안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.
GUI(Graphical User Interface) 애플리케이션을 개발할 때, Python의 기본 GUI 라이브러리인 Tkinter를 많이 사용합니다. 하지만 Tkinter의 기본 스타일은 오래되어 모던한 디자인을 적용하기 어렵습니다. 이를 보완하기 위해 등장한 것이 CustomTkinter입니다!
CustomTkinter는 Tkinter를 기반으로 하면서도 더 세련된 디자인과 다크 모드 지원, 커스텀 스타일 적용이 가능한 강력한 GUI 라이브러리입니다. 특히, 기본적으로 반응형 UI 요소를 제공하여 더욱 깔끔하고 현대적인 인터페이스를 구현할 수 있습니다.
이 글에서는 지난 글에서 다루었던 CustomTkinter 기초에 이어서 CustomTkinter의 다양한 위젯을 소개하고, 각 위젯을 어떻게 사용할 수 있는지 코드 예제와 함께 설명해 보겠습니다.
아래는 CustomTkinter에서 제공하는 주요 위젯들을 한 번에 보여주는 코드입니다. 이 후 각 위젯을 개별적으로 설명하겠습니다.
[코드]
import customtkinter as ctk
# CustomTkinter 설정
ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")
# 메인 윈도우 생성
root = ctk.CTk()
root.geometry("600x800")
root.title("CustomTkinter 위젯 예제")
# Switch 위젯 (모드 토글)
def toggle_mode():
if ctk.get_appearance_mode() == "Dark":
ctk.set_appearance_mode("Light")
else:
ctk.set_appearance_mode("Dark")
mode_toggle = ctk.CTkSwitch(root, text="모드 변경", command=toggle_mode)
mode_toggle.pack(pady=10, anchor="se", padx=10)
# Entry 위젯
entry = ctk.CTkEntry(root, placeholder_text="이름을 입력하세요")
entry.pack(pady=10)
# Slider 위젯 (라벨 위젯으로 슬라이더 값 표시)
label = ctk.CTkLabel(root, text="슬라이더 값: ")
label.pack(pady=10)
def slider_event(value):
label.configure(text=f"슬라이더 값: {int(value)}")
slider = ctk.CTkSlider(root, from_=0, to=100, command=slider_event)
slider.pack(pady=10)
# CheckBox 위젯
checkbox = ctk.CTkCheckBox(root, text="동의합니다")
checkbox.pack(pady=10)
# RadioButton 위젯
radio_var = ctk.StringVar(value="옵션1")
radiobutton1 = ctk.CTkRadioButton(root, text="옵션 1", variable=radio_var, value="옵션1")
radiobutton2 = ctk.CTkRadioButton(root, text="옵션 2", variable=radio_var, value="옵션2")
radiobutton1.pack()
radiobutton2.pack()
# ComboBox 위젯
combobox = ctk.CTkComboBox(root, values=["선택 1", "선택 2", "선택 3"])
combobox.pack(pady=10)
# ProgressBar 위젯
progressbar = ctk.CTkProgressBar(root)
progressbar.pack(pady=10)
progressbar.set(0.5) # 50% 진행 상태
# TabView 위젯
tabview = ctk.CTkTabview(root)
tabview.pack(pady=10)
# 탭 추가
tab1 = tabview.add("탭 1")
tab2 = tabview.add("탭 2")
# 각 탭에 내용 추가
ctk.CTkLabel(tab1, text="탭 1의 내용입니다").pack(pady=10)
ctk.CTkLabel(tab2, text="탭 2의 내용입니다").pack(pady=10)
# ScrollableFrame 위젯
scrollable_frame = ctk.CTkScrollableFrame(root, width=300, height=150)
scrollable_frame.pack(pady=10)
for i in range(10):
ctk.CTkLabel(scrollable_frame, text=f"항목 {i+1}").pack()
# 실행
root.mainloop()
[결과]
1. Switch 위젯
전환 가능한 스위치 버튼으로, ON/OFF 상태를 가집니다. CTkSwitch( ) 클래스를 이용해서 추가 가능하며, 이 스위치를 조작했을 때, 다크/라이트 모드가 변경되도록 함수를 정의하고 스위치 클래스와 연결해 보았습니다.
참고로 스위치는 pack( ) 메소드의 anchor 파라미터를 "e"로 설정해서 우측에 위치하도록 하였습니다.
- "n": north (위) / "s": south (아래) / "e": east (오른쪽) / "w": west (왼쪽) --> 조합도 가능 (ex. "ne")
[코드]
# Switch 위젯 (모드 토글)
def toggle_mode():
if ctk.get_appearance_mode() == "Dark":
ctk.set_appearance_mode("Light")
else:
ctk.set_appearance_mode("Dark")
mode_toggle = ctk.CTkSwitch(root, text="모드 변경", command=toggle_mode)
mode_toggle.pack(pady=10, anchor="ne", padx=10)
[결과]
2. Entry 위젯
Entry 위젯은 사용자가 텍스트를 입력할 수 있는 입력 필드입니다. Entry라는 용어가 익숙하지 않으신 분들은 Input 위젯이라고 생각하시면 되겠습니다. 이번 시간에는 입력 받은 값을 어떻게 사용하는지는 다루지 않고 이런 위젯이 있다는 것만 언급하고 넘어가도록 하겠습니다.
[코드]
entry = ctk.CTkEntry(root, placeholder_text="이름을 입력하세요")
entry.pack(pady=10)
[결과]
3. Slider 위젯
사용자가 드래그하여 값을 조정할 수 있는 슬라이더입니다. 슬라이더가 조정될 때 변하는 값을 관찰하기 위해서 지난 시간에 배웠던 Label 위젯을 먼저 추가해주었습니다. slider_event 함수는 CTkSlider의 값을 받아서 그 값을 포함한 Label을 출력해주도록 정의하였습니다.
CTkSlider는 "from_" 과 "to" 파라미터로 시작과 끝 값을 지정해주며, command 파라미터의 인자로 위에서 정의한 slider_event 함수를 입력해주었습니다.
여기서 slider_event의 파라미터인 value는 어떻게 입력되는지 잘 이해가 되지 않아서 찾아보니, 슬라이더의 현재 값이 자동으로 command 파라미터로 지정된 함수(slider_event)로 입력된다고 합니다.
[코드]
# Slider 위젯 (라벨 위젯으로 슬라이더 값 표시)
label = ctk.CTkLabel(root, text="슬라이더 값: ")
label.pack(pady=10)
def slider_event(value):
label.configure(text=f"슬라이더 값: {int(value)}")
slider = ctk.CTkSlider(root, from_=0, to=100, command=slider_event)
slider.pack(pady=10)
[결과]
4. CheckBox 위젯
사용자가 체크할 수 있는 체크박스입니다. 체크 박스 옆의 메시지를 "text" 파라미터로 설정할 수 있습니다.
[코드]
checkbox = ctk.CTkCheckBox(root, text="동의합니다")
checkbox.pack(pady=10)
[결과]
5. RadioButton 위젯
여러 개의 옵션 중 하나를 선택할 수 있는 버튼입니다. radio_var이란 변수를 설정해주고, 그 값을 CTkRadioButton( )의 variable 파라미터의 인자로 넣어주는 이유는 옵션을 선택했을 때 그 옵션의 "value"를 저장하기 위함입니다. 이 값을 다른 코드에서 입력으로 받아서 사용할 수 있도록 말입니다. 참고로 value는 문자열이 아니라 숫자도 가능합니다.
[코드]
radio_var = ctk.StringVar(value="옵션1")
radiobutton1 = ctk.CTkRadioButton(root, text="옵션 1", variable=radio_var, value="옵션1")
radiobutton2 = ctk.CTkRadioButton(root, text="옵션 2", variable=radio_var, value="옵션2")
radiobutton1.pack()
radiobutton2.pack()
[결과]
6. ComboBox 위젯
드롭다운 목록을 통해 값을 선택할 수 있는 콤보박스입니다. values 파라미터에 선택지를 리스트 타입으로 입력합니다.
[코드]
combobox = ctk.CTkComboBox(root, values=["선택 1", "선택 2", "선택 3"])
combobox.pack(pady=10)
[결과]
7. ProgressBar 위젯
진행 상태를 표시하는 프로그레스 바입니다. 프로그레스 바는 무언가 진행되는 정도를 보여주기 위한 위젯이기 때문에 해당 위젯 이외에 프로그레스 바의 수치를 10초간 10%씩 증가시키는 update_progress( ) 함수와 해당 함수를 실행하기 위한 버튼을 추가해주었습니다.
여기서 조금 어려운 포인트는 lambda 함수를 사용해 준 부분입니다. 여기서 lambda 함수를 써준 이유는 버튼 한 번의 클릭으로 두 가지 기능을 수행하기 위함입니다. progressbar.set(0)로 프로그레스 바의 값을 0으로 초기화 해준 다음 update_progress( ) 함수를 수행하게 됩니다.
[코드]
# ProgressBar 위젯
progressbar = ctk.CTkProgressBar(root)
progressbar.pack(pady=10)
progressbar.set(0) # 초기값 0%
def update_progress():
current_value = progressbar.get()
if current_value < 1.0:
progressbar.set(current_value + 0.1) # 10% 증가
root.after(1000, update_progress) # 1초 후 다시 실행
# 실행 버튼
start_button = ctk.CTkButton(root, text="실행", command=lambda: [progressbar.set(0), update_progress()])
start_button.pack(pady=10)
[결과]
8. TabView 위젯
여러 개의 탭을 포함하여 다양한 화면을 제공하는 위젯입니다. 먼저 CTkTabview( ) 클래스로 TabView 위젯을 하나 생성합니다. 메인 윈도우창인 root만 인자로 입력 받네요. 바로 이어서 방금 생성한 tabview 객체에 add( ) 메소드를 활용하여 "탭 1"과 "탭 2"를 생성해줍니다.
여기까지가 TabView 위젯을 생성하는 것이고, 다음 코드는 생성한 탭 안에 라벨 위젯을 넣는 코드입니다. 익숙한 코드인데 조금 다른 점은 pack( ) 메소드를 곧바로 붙여서 작성했다는 것과, 첫번째 인자를 root가 아니라 tab1과 tab2로 입력해주었다는 것입니다.
[코드]
# TabView 위젯
tabview = ctk.CTkTabview(root)
tabview.pack(pady=10)
# 탭 추가
tab1 = tabview.add("탭 1")
tab2 = tabview.add("탭 2")
# 각 탭에 내용 추가
ctk.CTkLabel(tab1, text="탭 1의 내용입니다").pack(pady=10)
ctk.CTkLabel(tab2, text="탭 2의 내용입니다").pack(pady=10)
[결과]
9. ScrollableFrame 위젯
스크롤 가능한 프레임으로, 많은 항목을 표시할 때 유용합니다. CTkScrollableFrame( ) 클래스는 width와 height 파라미터에 정수형 자료를 입력해서 크기를 조절할 수 있습니다. 그리고 그 안에 내용을 넣을 때는 위에서 탭에 내용을 추가 했을 때 처럼 Label 위젯의 첫번째 인자를 root가 아닌 방금 생성한 scrollable_frame 객체로 해주면 됩니다.
[코드]
scrollable_frame = ctk.CTkScrollableFrame(root, width=300, height=150)
scrollable_frame.pack(pady=10)
for i in range(10):
ctk.CTkLabel(scrollable_frame, text=f"항목 {i+1}").pack()
[결과]
이번 글에서는 CustomTkinter의 다양한 위젯들을 살펴보며 각각의 기능과 사용법을 익혔습니다. 이제 기본적인 위젯 사용법을 이해했으니, 다음 글에서는 간단한 프로젝트를 통해 실제로 GUI 프로그램을 어떻게 활용할 수 있는지 알아보겠습니다. CustomTkinter를 사용하여 실용적인 애플리케이션을 만들고, 이를 통해 GUI 개발의 흐름과 응용 방법을 배워보도록 하겠습니다.
'파이썬 패키지 > GUI 프로그램' 카테고리의 다른 글
[Python/GUI] 파이썬 GUI 초보도 쉽게! CustomTkinter로 깔끔한 UI 만들기(feat.다크 모드 지원) (0) | 2025.02.02 |
---|---|
PyQt를 상업적으로 사용하고 싶다면? 정답은 PySide6 (0) | 2022.01.05 |
[Python/Pyqt5] QWidget, QMainWindow, Qdialog 차이 총정리 (ft. Modal과 Modeless) (0) | 2021.12.06 |
[파이썬 GUI 프로그래밍] 잡플래닛 리뷰 정보 크롤링 GUI 프로그램 (2) | 2021.05.22 |
[파이썬 GUI 프로그래밍] PyQt5 기초_3강.Qt Designer로 내마음대로 GUI 구성하기 (0) | 2021.05.10 |