How to Schedule an Action with Tkinter after() method

2024. 4. 2. 09:34GUI/tkinter

요약 : 이 튜토리얼에서는 Tkinter after() 메소드를 사용하여 시간 초과가 경과한 후 작업을 예약하는 방법을 배웁니다 .

 

after()Tkinter 방법 소개

 

모든 Tkinter after() 위젯에는 다음 구문을 사용하는 메소드가 있습니다.

 

widget.after(delay, callback=None)

 

코드 언어: Python ( 파이썬 ) after() 메소드는 Tkinter의 메인 루프 내에서 delay 밀리초(ms) 후에 callback 함수를 한 번 호출합니다.

callback를 제공하지 않으면, after()메서드는 time.sleep() 함수 처럼 동작합니다. 그러나 after() 메서드에서는 단위가 초 대신 밀리초를 사용합니다.

 

Tkinter after() 메소드 예

 

다음 프로그램을 봅시다.

 
import tkinter as tk
from tkinter import ttk
import time


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Tkinter after() Demo')
        self.geometry('300x100')

        self.style = ttk.Style(self)

        self.button = ttk.Button(self, text='Wait 3 seconds')
        self.button['command'] = self.start
        self.button.pack(expand=True, ipadx=10, ipady=5)

    def start(self):
        self.change_button_color('red')
        time.sleep(3)
        self.change_button_color('black')

    def change_button_color(self, color):
        self.style.configure('TButton', foreground=color)


if __name__ == "__main__":
    app = App()
    app.mainloop()
 

이 프로그램은 버튼으로 구성됩니다. 버튼을 클릭하면:

  • 먼저 버튼의 색상이 빨간색으로 변합니다.
  • 그런 다음 프로그램은
  • 3초 동안 절전 모드로 전환됩니다.
  • 마지막으로 버튼의 색상이 검은색으로 변합니다.

그러나 프로그램을 실행하고 버튼을 클릭하면 버튼의 색상이 전혀 변하지 않는 것을 볼 수 있습니다. 또한 창이 다음과 같이 3초 동안 정지됩니다.

 

 

그 이유는 sleep()함수가 메인 스레드 실행을 일시 중단했기 때문입니다

 

. 따라서 Tkinter는 GUI를 업데이트할 수 없습니다.

문제를 해결하려면 after() 메서드를 사용하여 기본 스레드 실행을 일시 중단하는 대신 버튼 색상을 업데이트하는 작업을 예약할 수 있습니다. 예를 들어:

 
import tkinter as tk
from tkinter import ttk
import time


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Tkinter after() Demo')
        self.geometry('300x100')

        self.style = ttk.Style(self)

        self.button = ttk.Button(self, text='Wait 3 seconds')
        self.button['command'] = self.start
        self.button.pack(expand=True, ipadx=10, ipady=5)

    def start(self):
        self.change_button_color('red')
        self.after(3000,lambda: self.change_button_color('black'))


    def change_button_color(self, color):
        self.style.configure('TButton', foreground=color)
        print(color)


if __name__ == "__main__":
    app = App()
    app.mainloop()

 

 

Tkinter after() 메소드를 사용하는 이유

 

Python 프로그램은 하나 또는 여러 개의 스레드를 가질 수 있습니다. Tkinter 애플리케이션을 시작하면 메인 스레드에서 실행됩니다.

Tkinter의 메인 루프는 메인 스레드에서 시작해야 합니다. 이벤트 처리 및 GUI 업데이트를 담당합니다.

메인 스레드에서 장기 실행 작업을 시작하면 GUI가 정지되고 사용자 이벤트에 응답하지 않습니다.

장기 실행 작업이 메인 스레드를 차단하는 것을 방지하려면 after() 메서드를 사용하여 지정된 시간보다 일찍 실행되지 않는 작업을 예약할 수 있습니다.

Tkinter는 메인 스레드가 바쁘지 않을 때 메인 스레드에서 콜백을 실행합니다 .

 

실용적인 Tkinter after() 메소드 예

 

다음 프로그램은 디지털 시계를 표시합니다. 매초마다 현재 시간을 업데이트하는 after() 메서드를 사용합니다.

 
import tkinter as tk
from tkinter import ttk
import time


class DigitalClock(tk.Tk):
    def __init__(self):
        super().__init__()

        # configure the root window
        self.title('Digital Clock')
        self.resizable(0, 0)
        self.geometry('250x80')
        self['bg'] = 'black'

        # change the background color to black
        self.style = ttk.Style(self)
        self.style.configure(
            'TLabel',
            background='black',
            foreground='red')

        # label
        self.label = ttk.Label(
            self,
            text=self.time_string(),
            font=('Digital-7', 40))

        self.label.pack(expand=True)

        # schedule an update every 1 second
        self.label.after(1000, self.update)

    def time_string(self):
        return time.strftime('%H:%M:%S')

    def update(self):
        """ update the label every 1 second """

        self.label.configure(text=self.time_string())

        # schedule another timer
        self.label.after(1000, self.update)


if __name__ == "__main__":
    clock = DigitalClock()
    clock.mainloop()

 

 

작동 방식.

다음 메서드는 현재 시간을 문자열 형식으로 반환합니다.

 
def time_string(self):
    return time.strftime('%H:%M:%S')
 
  Cell In[4], line 1
    def time_string(self):
       ^
SyntaxError: invalid non-printable character U+00A0
 

__init__() 메서드는 after() 메서드를 사용하여 매초마다 레이블에 대한 현재 시간을 업데이트하는 작업을 예약합니다.

 
self.label.after(1000, self.update)
 

update() 메서드에서 현재 시간을 레이블로 업데이트하고 1초 후에 다른 업데이트를 예약합니다.

 
def update(self):
    """ update the label every 1 second """

    self.label.configure(text=self.time_string())

    # schedule another timer
    self.label.after(1000, self.update)
 

이 프로그램은 1001fonts.com의 Digital 7 글꼴을 사용합니다.

 

요약

 
  • Tkinter after()메소드를 사용하여 시간 초과가 경과한 후 실행될 작업을 예약합니다.
  • after() 메서드에 전달된 콜백은 여전히 ​​기본 스레드에서 실행됩니다. 따라서 after() 메서드를 사용하여 장기 실행 작업을 수행하는 것을 피해야 합니다.
 
 

How to Schedule an Action With Tkinter after() method

In this tutorial, you'll learn how to use the Tkinter after() method to schedule an action after a timeout has elapsed.

www.pythontutorial.net