Tkinter를 사용한 Python GUI 프로그래밍2

2023. 12. 20. 19:09python/basic

widgetsFrameWidget 사용하여 프레임에 위젯 할당

다음과 같은 5개의 위젯만 사용하여 작업합니다.

  1. Label
  2. Button
  3. Entry
  4. Text
  5. Frame

지금까지 본 네 가지 위젯과 Frame 위젯이 있습니다. Frame 위젯은 애플리케이션에서 위젯 레이아웃을 구성하는 데 중요합니다. 다음 스크립트는 빈 Frame 위젯을 생성하여 기본 애플리케이션 창에 할당합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()
frame = tk.Frame()
frame.pack()

window.mainloop()

위젯의 master 속성을 설정하여 프레임에 위젯을 할당할 수 있습니다.

In [ ]:
frame = tk.Frame()
label = tk.Label(master=frame)
In [ ]:
import tkinter as tk

window = tk.Tk()

frame_a = tk.Frame()
frame_b = tk.Frame()

label_a = tk.Label(master=frame_a, text="I'm in Frame A")
label_a.pack()

label_b = tk.Label(master=frame_b, text="I'm in Frame B")
label_b.pack()

frame_a.pack()
frame_b.pack()

window.mainloop()

frame_a은 frame_b 이전 창에 압축되어 있습니다. 이제 frame_a.pack() 및 frame_b.pack()의 순서를 바꾸면 어떻게 되는지 확인해 보세요.

In [ ]:
import tkinter as tk

window = tk.Tk()

frame_a = tk.Frame()
label_a = tk.Label(master=frame_a, text="I'm in Frame A")
label_a.pack()

frame_b = tk.Frame()부조를 사용하여 프레임 모양 조정
label_b = tk.Label(master=frame_b, text="I'm in Frame B")
label_b.pack()

# Swap the order of `frame_a` and `frame_b`
frame_b.pack()
frame_a.pack()

window.mainloop()

이제 label_b가 맨 위에 있습니다. label_b는 frame_b에 할당되어 있으므로 frame_b가 위치한 곳으로 이동합니다.

부조를 사용하여 프레임 모양 조정

Frame 위젯은 프레임 주위에 테두리를 만드는 relief 속성으로 구성할 수 있습니다. relief를 다음 값 중 하나로 설정할 수 있습니다.

  • tk.FLAT: 테두리 효과가 없습니다(기본값)
  • tk.SUNKEN: 가라앉은 효과를 만듭니다
  • tk.RAISED: 상승 효과 생성
  • tk.GROOVE: 홈이 있는 테두리 효과 생성
  • tk.RIDGE: 능선 효과 생성
In [ ]:
import tkinter as tk

border_effects = {
    "flat": tk.FLAT,
    "sunken": tk.SUNKEN,
    "raised": tk.RAISED,
    "groove": tk.GROOVE,
    "ridge": tk.RIDGE,
}

window = tk.Tk()

for relief_name, relief in border_effects.items():
    frame = tk.Frame(master=window, relief=relief, borderwidth=5)
    frame.pack(side=tk.LEFT)
    label = tk.Label(master=frame, text=relief_name)
    label.pack()

window.mainloop()

이 스크립트에 대한 분석은 다음과 같습니다.

  • 3~9행 키가 사용 가능한 다양한 완화 효과의 이름인 사전을 만듭니다. Tkinter에서 값은 해당 Tkinter 객체입니다. 이 사전은 border_effects 변수에 할당됩니다.
  • 라인 13은 border_effects를 더하기 위하여 for 루프를 시작합니다.
  • 14행은 새로운 Frame 위젯을 생성하고 이를 window 개체에 할당합니다. relief 속성은 border_effects 사전의 해당 구호로 설정되고 효과가 눈에 보이도록 하기 위하여 border 속성은 5로 설정됩니다.
  • 15행은 window을 사용하여 Frame를 압축합니다. 키워드 인수는 Tkinter에게 객체를 패킹할 방향을 알려줍니다. 다음 섹션에서 이것이 어떻게 작동하는지 자세히 알아볼 것입니다.
  • 16행과 17행 부조의 이름을 표시하는 Label widget을 생성하고 방금 생성한 개체인 frame을 생성합니다.

이 이미지에서는 다음과 같은 효과를 볼 수 있습니다.

  • tk.FLAT : 평평한 것처럼 보이는 프레임을 만듭니다.
  • tk.SUNKEN : 프레임이 창 안으로 들어간 것처럼 보이도록 테두리를 추가합니다.
  • tk.RAISED : 화면에서 튀어나온 것처럼 보이도록 프레임에 테두리를 제공합니다.
  • tk.GROOVE : 평평한 프레임 주위에 움푹 들어간 홈으로 나타나는 테두리를 추가합니다.
  • tk.RIDGE : 프레임 가장자리 주위에 돌출된 입술 모양을 제공합니다.

위젯 명명 규칙 이해

참고: 때로는 변수에 할당하지 않고 새 위젯을 정의할 수도 있습니다. 동일한 코드 줄에서 .pack() 메소드를 직접 호출합니다.

>>> tk.Label(text="Hello, Tkinter").pack()

이는 나중에 위젯의 인스턴스를 참조하지 않으려는 경우 도움이 될 수 있습니다.

이해도를 확인하세요

폭이 40 텍스트 단위이고 흰색 배경과 검은색 텍스트가 있는 Entry 위젯을 표시하는 완전한 스크립트를 작성하세요. .insert()를 사용하면 What is your name?라는 텍스트를 위젯에 표시할 수 있습니다.

다음은 bg 및 fg 매개변수를 사용하여 Entry 위젯의 배경색과 전경색을 설정하는 솔루션 중 하나입니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

entry = tk.Entry(width=40, bg="white", fg="black")
entry.pack()

entry.insert(0, "What is your name?")

window.mainloop()

대부분의 시스템에서 Entry 위젯의 기본 배경색은 흰색이고 기본 전경색은 검정색입니다. 따라서 bg 및 fg 매개변수를 제외하고 동일한 창을 생성할 수 있습니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

entry = tk.Entry(width=40)
entry.pack()

entry.insert(0, "What is your name?")

window.mainloop()

지오메트리 관리자로 레이아웃 제어

  • .place()
  • .grid()

.pack() 기하학 관리자

.pack() 기하학 관리자는 압축 알고리즘을 사용하여 위젯을 Frame 또는 지정된 순서로 창을 표시합니다. 특정 위젯의 경우 패킹 알고리즘에는 두 가지 기본 단계가 있습니다.

  • 위젯을 수용할 만큼 충분히 크고 나머지 너비(또는 높이)를 채우는 공백이 있는 창에 소포라는 직사각형 영역을 계산합니다.
  • 다른 위치가 지정되지 않는 한 위젯을 구획의 중앙에 배치합니다.
In [ ]:
import tkinter as tk

window = tk.Tk()

frame1 = tk.Frame(master=window, width=100, height=100, bg="red")
frame1.pack()

frame2 = tk.Frame(master=window, width=50, height=50, bg="yellow")
frame2.pack()

frame3 = tk.Frame(master=window, width=25, height=25, bg="blue")
frame3.pack()

window.mainloop()

.pack()은 위젯 배치를 보다 정확하게 구성하기 위해 몇 가지 키워드 인수를 허용합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

frame1 = tk.Frame(master=window, height=100, bg="red")
frame1.pack(fill=tk.X)

frame2 = tk.Frame(master=window, height=50, bg="yellow")
frame2.pack(fill=tk.X)

frame3 = tk.Frame(master=window, height=25, bg="blue")
frame3.pack(fill=tk.X)

window.mainloop()
  • tk.TOP
  • tk.BOTTOM
  • tk.LEFT
  • tk.RIGHT

설정하지 않으면 side, .pack()는 자동으로 tk.TOP를 사용하고 상단에 새 위젯을 배치합니다. 창

In [ ]:
import tkinter as tk

window = tk.Tk()

frame1 = tk.Frame(master=window, width=200, height=100, bg="red")
frame1.pack(fill=tk.Y, side=tk.LEFT)

frame2 = tk.Frame(master=window, width=100, bg="yellow")
frame2.pack(fill=tk.Y, side=tk.LEFT)

frame3 = tk.Frame(master=window, width=50, bg="blue")
frame3.pack(fill=tk.Y, side=tk.LEFT)

window.mainloop()

레이아웃이 실제로 반응하도록 하려면 width 및 height 속성을 ​​사용하여 프레임의 초기 크기를 설정할 수 있습니다. 그런 다음 의 fill 키워드 인수를 로 설정하고 키워드 인수를 다음으로 설정합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

frame1 = tk.Frame(master=window, width=200, height=100, bg="red")
frame1.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)

frame2 = tk.Frame(master=window, width=100, bg="yellow")
frame2.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)

frame3 = tk.Frame(master=window, width=50, bg="blue")
frame3.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)

window.mainloop()

.place() 기하학 관리자

.place()을 사용하여 위젯이 창에서 차지해야 하는 정확한 위치를 제어할 수 있습니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

frame = tk.Frame(master=window, width=150, height=150)
frame.pack()

label1 = tk.Label(master=frame, text="I'm at (0, 0)", bg="red")
label1.place(x=0, y=0)

label2 = tk.Label(master=frame, text="I'm at (75, 75)", bg="yellow")
label2.place(x=75, y=75)

window.mainloop()
.place의 단점
  • 레이아웃은 .place()으로 관리하기 어려울 수 있습니다. 애플리케이션에 위젯이 많은 경우 특히 그렇습니다.
  • .place()로 생성된 레이아웃은 반응하지 않습니다. 창 크기가 조정되어도 변경되지 않습니다.

.grid() 기하학 관리자

가장 자주 사용하게 될 지오메트리 관리자는 .grid()입니다. 이는 .pack()의 모든 기능을 더 쉽게 이해하고 유지 관리할 수 있는 형식으로 제공합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

for i in range(3):
    for j in range(3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack()

window.mainloop()
In [ ]:
.grid():에 대한 두 개의 키워드 인수로 제어됩니다.

- padx가로 방향으로 패딩을 추가합니다.
- pady세로 방향으로 패딩을 추가합니다.
In [ ]:
import tkinter as tk

window = tk.Tk()

for i in range(3):
    for j in range(3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j, padx=5, pady=5)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack()

window.mainloop()

다음 코드는 x 및 y 방향 모두에서 각 레이블 주위에 5픽셀의 추가 패딩을 추가한다는 점을 제외하면 이전 코드와 거의 동일합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

for i in range(3):
    for j in range(3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j, padx=5, pady=5)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack(padx=5, pady=5)

window.mainloop()
  • 색인: 구성하려는 그리드 열 또는 행의 인덱스 또는 동시에 여러 행 또는 열을 구성하기 위한 인덱스 목록
  • 가중치: 다른 열 및 행을 기준으로 창 크기 조정에 열이나 행이 응답하는 방식을 결정하는 weight라는 키워드 인수
  • 최소 크기: 행 높이 또는 열 너비의 최소 크기를 픽셀 단위로 설정하는 minsize라는 키워드 인수
In [ ]:
import tkinter as tk

window = tk.Tk()

for i in range(3):
    window.columnconfigure(i, weight=1, minsize=75)
    window.rowconfigure(i, weight=1, minsize=50)

    for j in range(0, 3):
        frame = tk.Frame(
            master=window,
            relief=tk.RAISED,
            borderwidth=1
        )
        frame.grid(row=i, column=j, padx=5, pady=5)
        label = tk.Label(master=frame, text=f"Row {i}\nColumn {j}")
        label.pack(padx=5, pady=5)

window.mainloop()

기본적으로 위젯은 그리드 셀의 중앙에 위치합니다. 예를 들어, 다음 코드는 두 개의 Label 위젯을 생성하고 이를 열 1개와 행 2개로 구성된 그리드에 배치합니다.

In [ ]:
import tkinter as tk

window = tk.Tk()
window.columnconfigure(0, minsize=250)
window.rowconfigure([0, 1], minsize=100)

label1 = tk.Label(text="A")
label1.grid(row=0, column=0)

label2 = tk.Label(text="B")
label2.grid(row=1, column=0)

window.mainloop()

다음 문자 중 하나 이상이 포함된 문자열을 허용하는 sticky 매개변수를 사용하여 그리드 셀 내부의 각 라벨 위치를 변경할 수 있습니다.

  • "n" 또는 "N" : 셀의 상단 중앙 부분에 정렬
  • "e" 또는 "E" : 셀의 오른쪽 중앙에 정렬
  • "s" 또는 "S" : 셀의 하단 중앙 부분에 정렬
  • "w" 또는 "W" : 셀의 왼쪽 중앙에 정렬
In [ ]:
import tkinter as tk

window = tk.Tk()
window.columnconfigure(0, minsize=250)
window.rowconfigure([0, 1], minsize=100)

label1 = tk.Label(text="A")
label1.grid(row=0, column=0, sticky="n")

label2 = tk.Label(text="B")
label2.grid(row=1, column=0, sticky="n")

window.mainloop()

단일 문자열에 여러 문자를 결합하여 각 레이블을 그리드 셀 모서리에 배치할 수 있습니다.

In [ ]:
import tkinter as tk

window = tk.Tk()
window.columnconfigure(0, minsize=250)
window.rowconfigure([0, 1], minsize=100)

label1 = tk.Label(text="A")
label1.grid(row=0, column=0, sticky="ne")

label2 = tk.Label(text="B")
label2.grid(row=1, column=0, sticky="sw")

window.mainloop()

그리드를 채우려면 "ns"를 지정하여 위젯이 셀을 세로 방향으로 채우도록 하거나 "ew"을 지정하여 셀을 가로 방향으로 채울 수 있습니다. . 전체 셀을 채우려면 sticky를 "nsew"로 설정하세요. 다음 예에서는 이러한 각 옵션을 보여줍니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

window.rowconfigure(0, minsize=50)
window.columnconfigure([0, 1, 2, 3], minsize=50)

label1 = tk.Label(text="1", bg="black", fg="white")
label2 = tk.Label(text="2", bg="black", fg="white")
label3 = tk.Label(text="3", bg="black", fg="white")
label4 = tk.Label(text="4", bg="black", fg="white")

label1.grid(row=0, column=0)
label2.grid(row=0, column=1, sticky="ew")
label3.grid(row=0, column=2, sticky="ns")
label4.grid(row=0, column=3, sticky="nsew")

window.mainloop()

이해도를 확인하세요

In [ ]:
import tkinter as tk

# Create a new window with the title "Address Entry Form"
window = tk.Tk()
window.title("Address Entry Form")

# Create a new frame `frm_form` to contain the Label
# and Entry widgets for entering address information
frm_form = tk.Frame(relief=tk.SUNKEN, borderwidth=3)
# Pack the frame into the window
frm_form.pack()

# Create the Label and Entry widgets for "First Name"
lbl_first_name = tk.Label(master=frm_form, text="First Name:")
ent_first_name = tk.Entry(master=frm_form, width=50)
# Use the grid geometry manager to place the Label and
# Entry widgets in the first and second columns of the
# first row of the grid
lbl_first_name.grid(row=0, column=0, sticky="e")
ent_first_name.grid(row=0, column=1)

# Create the Label and Entry widgets for "Last Name"
lbl_last_name = tk.Label(master=frm_form, text="Last Name:")
ent_last_name = tk.Entry(master=frm_form, width=50)
# Place the widgets in the second row of the grid
lbl_last_name.grid(row=1, column=0, sticky="e")
ent_last_name.grid(row=1, column=1)

# Create the Label and Entry widgets for "Address Line 1"
lbl_address1 = tk.Label(master=frm_form, text="Address Line 1:")
ent_address1 = tk.Entry(master=frm_form, width=50)
# Place the widgets in the third row of the grid
lbl_address1.grid(row=2, column=0, sticky="e")
ent_address1.grid(row=2, column=1)

# Create the Label and Entry widgets for "Address Line 2"
lbl_address2 = tk.Label(master=frm_form, text="Address Line 2:")
ent_address2 = tk.Entry(master=frm_form, width=50)
# Place the widgets in the fourth row of the grid
lbl_address2.grid(row=3, column=0, sticky=tk.E)
ent_address2.grid(row=3, column=1)

# Create the Label and Entry widgets for "City"
lbl_city = tk.Label(master=frm_form, text="City:")
ent_city = tk.Entry(master=frm_form, width=50)
# Place the widgets in the fifth row of the grid
lbl_city.grid(row=4, column=0, sticky=tk.E)
ent_city.grid(row=4, column=1)

# Create the Label and Entry widgets for "State/Province"
lbl_state = tk.Label(master=frm_form, text="State/Province:")
ent_state = tk.Entry(master=frm_form, width=50)
# Place the widgets in the sixth row of the grid
lbl_state.grid(row=5, column=0, sticky=tk.E)
ent_state.grid(row=5, column=1)

# Create the Label and Entry widgets for "Postal Code"
lbl_postal_code = tk.Label(master=frm_form, text="Postal Code:")
ent_postal_code = tk.Entry(master=frm_form, width=50)
# Place the widgets in the seventh row of the grid
lbl_postal_code.grid(row=6, column=0, sticky=tk.E)
ent_postal_code.grid(row=6, column=1)

# Create the Label and Entry widgets for "Country"
lbl_country = tk.Label(master=frm_form, text="Country:")
ent_country = tk.Entry(master=frm_form, width=50)
# Place the widgets in the eight row of the grid
lbl_country.grid(row=7, column=0, sticky=tk.E)
ent_country.grid(row=7, column=1)

# Create a new frame `frm_buttons` to contain the
# Submit and Clear buttons. This frame fills the
# whole window in the horizontal direction and has
# 5 pixels of horizontal and vertical padding.
frm_buttons = tk.Frame()
frm_buttons.pack(fill=tk.X, ipadx=5, ipady=5)

# Create the "Submit" button and pack it to the
# right side of `frm_buttons`
btn_submit = tk.Button(master=frm_buttons, text="Submit")
btn_submit.pack(side=tk.RIGHT, padx=10, ipadx=10)

# Create the "Clear" button and pack it to the
# right side of `frm_buttons`
btn_clear = tk.Button(master=frm_buttons, text="Clear")
btn_clear.pack(side=tk.RIGHT, ipadx=10)

# Start the application
window.mainloop()
In [ ]:
import tkinter as tk

# Create a new window with the title "Address Entry Form"
window = tk.Tk()
window.title("Address Entry Form")

# Create a new frame `frm_form` to contain the Label
# and Entry widgets for entering address information
frm_form = tk.Frame(relief=tk.SUNKEN, borderwidth=3)
# Pack the frame into the window
frm_form.pack()

# List of field labels
labels = [
    "First Name:",
    "Last Name:",
    "Address Line 1:",
    "Address Line 2:",
    "City:",
    "State/Province:",
    "Postal Code:",
    "Country:",
]

# Loop over the list of field labels
for idx, text in enumerate(labels):
    # Create a Label widget with the text from the labels list
    label = tk.Label(master=frm_form, text=text)
    # Create an Entry widget
    entry = tk.Entry(master=frm_form, width=50)
    # Use the grid geometry manager to place the Label and
    # Entry widgets in the row whose index is idx
    label.grid(row=idx, column=0, sticky="e")
    entry.grid(row=idx, column=1)

# Create a new frame `frm_buttons` to contain the
# Submit and Clear buttons. This frame fills the
# whole window in the horizontal direction and has
# 5 pixels of horizontal and vertical padding.
frm_buttons = tk.Frame()
frm_buttons.pack(fill=tk.X, ipadx=5, ipady=5)

# Create the "Submit" button and pack it to the
# right side of `frm_buttons`
btn_submit = tk.Button(master=frm_buttons, text="Submit")
btn_submit.pack(side=tk.RIGHT, padx=10, ipadx=10)

# Create the "Clear" button and pack it to the
# right side of `frm_buttons`
btn_clear = tk.Button(master=frm_buttons, text="Clear")
btn_clear.pack(side=tk.RIGHT, ipadx=10)

# Start the application
window.mainloop()

애플리케이션을 대화형으로 만들기

이벤트 및 이벤트 처리기 사용

이벤트 개체가 포함된 events이라는 목록이 있다고 가정합니다. 프로그램에서 이벤트가 발생할 때마다 새 이벤트 객체가 events에 자동으로 추가됩니다.

In [ ]:
# Assume that this list gets updated automatically
events = []

# Run the event loop
while True:
    # If the event list is empty, then no events have occurred
    # and you can skip to the next iteration of the loop
    if events == []:
        continue

    # If execution reaches this point, then there is at least one
    # event object in the event list
    event = events[0]

이벤트가 키 누르기 이벤트 객체인 경우 event .type 속성이 문자열로 설정된 "keypress" 속성을 ​​가지고 있다고 가정합니다.

In [ ]:
events = []

# Create an event handler
def handle_keypress(event):
    """Print the character associated to the key pressed"""
    print(event.char)

while True:
    if events == []:
        continue

    event = events[0]

    # If event is a keypress event object
    if event.type == "keypress":
        # Call the keypress event handler
        handle_keypress(event)
  1. 발생한 이벤트 목록을 유지합니다.
  2. 해당 목록에 새 이벤트가 추가될 때마다 이벤트 핸들러가 실행됩니다.
In [ ]:
import tkinter as tk

# Create a window object
window = tk.Tk()

# Create an event handler
def handle_keypress(event):
    """Print the character associated to the key pressed"""
    print(event.char)

# Run the event loop
window.mainloop()

window.mainloop() 은 많은 일을 처리해 주지만 위 코드에는 뭔가 빠진 것이 있습니다. Tkinter는 handle_keypress()를 언제 사용해야 하는지 어떻게 알 수 있나요? Tkinter 위젯에는 이 목적을 위해 .bind()라는 메소드가 있습니다.

사용.bind()

In [ ]:
import tkinter as tk

window = tk.Tk()

def handle_keypress(event):
    """Print the character associated to the key pressed"""
    print(event.char)

# Bind keypress event to handle_keypress()
window.bind("<Key>", handle_keypress)

window.mainloop()

window.bind()항상 최소한 두 개의 인수를 사용합니다.

  1. 이벤트는 "<event_name>" 형식의 문자열로 표시됩니다. 여기서 event_name는 Tkinter의 이벤트 중 하나일 수 있습니다
  2. 이벤트가 발생할 때마다 호출되는 함수의 이름인 이벤트 핸들러
In [ ]:
def handle_click(event):
    print("The button was clicked!")

button = tk.Button(text="Click me!")

button.bind("<Button-1>", handle_click)

사용 command

모든 Button 위젯에는 기능에 할당할 수 있는 command 속성이 있습니다. 버튼을 누를 때마다 기능이 실행됩니다.

In [ ]:
import tkinter as tk

window = tk.Tk()

window.rowconfigure(0, minsize=50, weight=1)
window.columnconfigure([0, 1, 2], minsize=50, weight=1)

btn_decrease = tk.Button(master=window, text="-")
btn_decrease.grid(row=0, column=0, sticky="nsew")

lbl_value = tk.Label(master=window, text="0")
lbl_value.grid(row=0, column=1)

btn_increase = tk.Button(master=window, text="+")
btn_increase.grid(row=0, column=2, sticky="nsew")

window.mainloop()

사전 스타일 아래 첨자 표기법으로 text 속성에 액세스하여 레이블에서 텍스트를 검색할 수 있습니다.

In [ ]:
label = tk.Label(text="Hello")

# Retrieve a label's text
text = label["text"]

# Set new text for the label
label["text"] = "Good bye"

라벨의 텍스트를 가져오고 설정하는 방법을 알았으니 이제 의 값을 1씩 늘리는 increase() 함수를 작성하세요.

In [ ]:
import tkinter as tk

def increase():
    value = int(lbl_value["text"])
    lbl_value["text"] = f"{value + 1}"

# ...

increase()은 lbl_value에서 텍스트를 가져와 int()를 사용하여 정수로 변환합니다. 그런 다음 이 값을 1만큼 늘리고 라벨의 text 속성을 ​​이 새 값으로 설정합니다. 또한 decrease() value_label 값을 1씩 줄여야 합니다.

In [ ]:
# ...

def decrease():
    value = int(lbl_value["text"])
    lbl_value["text"] = f"{value - 1}"

# ...

버튼을 기능에 연결하려면 버튼의 command 속성에 기능을 할당하세요. 버튼을 인스턴스화할 때 이 작업을 수행할 수 있습니다.

In [ ]:
# ...

btn_decrease = tk.Button(master=window, text="-", command=decrease)
btn_decrease.grid(row=0, column=0, sticky="nsew")

lbl_value = tk.Label(master=window, text="0")
lbl_value.grid(row=0, column=1)

btn_increase = tk.Button(master=window, text="+", command=increase)
btn_increase.grid(row=0, column=2, sticky="nsew")

window.mainloop()
In [ ]:
import tkinter as tk

def increase():
    value = int(lbl_value["text"])
    lbl_value["text"] = f"{value + 1}"

def decrease():
    value = int(lbl_value["text"])
    lbl_value["text"] = f"{value - 1}"

window = tk.Tk()

window.rowconfigure(0, minsize=50, weight=1)
window.columnconfigure([0, 1, 2], minsize=50, weight=1)

btn_decrease = tk.Button(master=window, text="-", command=decrease)
btn_decrease.grid(row=0, column=0, sticky="nsew")

lbl_value = tk.Label(master=window, text="0")
lbl_value.grid(row=0, column=1)

btn_increase = tk.Button(master=window, text="+", command=increase)
btn_increase.grid(row=0, column=2, sticky="nsew")

window.mainloop()
  • 위젯을 사용하여 사용자 인터페이스의 구성요소를 만듭니다.
  • 형상 관리자를 사용하여 애플리케이션의 레이아웃을 제어하세요.
  • 다양한 구성요소와 상호작용하여 사용자 입력을 캡처하고 변환하는 이벤트 핸들러를 작성하세요.

이해도를 확인하세요

6각형 주사위 굴리기를 시뮬레이션하는 프로그램을 작성하세요. Roll 텍스트가 포함된 버튼이 하나 있어야 합니다. 사용자가 버튼을 클릭하면 1부터 6까지의 임의의 정수가 표시되어야 합니다.

In [ ]:
import random
import tkinter as tk

def roll():
    lbl_result["text"] = str(random.randint(1, 6))

window = tk.Tk()
window.columnconfigure(0, minsize=150)
window.rowconfigure([0, 1], minsize=50)

btn_roll = tk.Button(text="Roll", command=roll)
lbl_result = tk.Label()

btn_roll.grid(row=0, column=0, sticky="nsew")
lbl_result.grid(row=1, column=0)

window.mainloop()

온도 변환기 구축(예제 앱)

In [ ]:
import tkinter as tk

def fahrenheit_to_celsius():
    """Convert the value for Fahrenheit to Celsius and insert the
    result into lbl_result.
    """
    fahrenheit = ent_temperature.get()
    celsius = (5 / 9) * (float(fahrenheit) - 32)
    lbl_result["text"] = f"{round(celsius, 2)} \N{DEGREE CELSIUS}"

# Set up the window
window = tk.Tk()
window.title("Temperature Converter")
window.resizable(width=False, height=False)

# Create the Fahrenheit entry frame with an Entry
# widget and label in it
frm_entry = tk.Frame(master=window)
ent_temperature = tk.Entry(master=frm_entry, width=10)
lbl_temp = tk.Label(master=frm_entry, text="\N{DEGREE FAHRENHEIT}")

# Layout the temperature Entry and Label in frm_entry
# using the .grid() geometry manager
ent_temperature.grid(row=0, column=0, sticky="e")
lbl_temp.grid(row=0, column=1, sticky="w")

# Create the conversion Button and result display Label
btn_convert = tk.Button(
    master=window,
    text="\N{RIGHTWARDS BLACK ARROW}",
    command=fahrenheit_to_celsius
)
lbl_result = tk.Label(master=window, text="\N{DEGREE CELSIUS}")

# Set up the layout using the .grid() geometry manager
frm_entry.grid(row=0, column=0, padx=10)
btn_convert.grid(row=0, column=1, pady=10)
lbl_result.grid(row=0, column=2, padx=10)

# Run the application
window.mainloop()

텍스트 편집기 만들기(예제 앱)

In [ ]:
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename

def open_file():
    """Open a file for editing."""
    filepath = askopenfilename(
        filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")]
    )
    if not filepath:
        return
    txt_edit.delete("1.0", tk.END)
    with open(filepath, mode="r", encoding="utf-8") as input_file:
        text = input_file.read()
        txt_edit.insert(tk.END, text)
    window.title(f"Simple Text Editor - {filepath}")

def save_file():
    """Save the current file as a new file."""
    filepath = asksaveasfilename(
        defaultextension=".txt",
        filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")],
    )
    if not filepath:
        return
    with open(filepath, mode="w", encoding="utf-8") as output_file:
        text = txt_edit.get("1.0", tk.END)
        output_file.write(text)
    window.title(f"Simple Text Editor - {filepath}")

window = tk.Tk()
window.title("Simple Text Editor")

window.rowconfigure(0, minsize=800, weight=1)
window.columnconfigure(1, minsize=800, weight=1)

txt_edit = tk.Text(window)
frm_buttons = tk.Frame(window, relief=tk.RAISED, bd=2)
btn_open = tk.Button(frm_buttons, text="Open", command=open_file)
btn_save = tk.Button(frm_buttons, text="Save As...", command=save_file)

btn_open.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
btn_save.grid(row=1, column=0, sticky="ew", padx=5)

frm_buttons.grid(row=0, column=0, sticky="ns")
txt_edit.grid(row=0, column=1, sticky="nsew")

window.mainloop()