[PYTHON] [Tkinter] Verbessern Sie die Reaktionsfähigkeit der Benutzeroberfläche

1. Zuallererst

Heute werde ich erklären, wie Threading verwendet wird, um die Reaktionsfähigkeit beim Erstellen einer GUI-Anwendung zu verbessern.

2. Was Sie tun möchten

Entwerfen Sie einen einfachen GUI-Bildschirm wie in der folgenden Abbildung gezeigt. Wenn Sie auf die Schaltfläche oben klicken, wird sie unten in der Reihenfolge 0 bis 9 angezeigt. image.png Schreiben wir den Code sofort in Tkinter.

3. Code reagiert nicht

Zuerst habe ich den folgenden Code geschrieben. Wenn die Taste gedrückt wird, wird _main_func () ausgeführt. _main_func () ist eine Funktion, die mit der For-Anweisung von 0 bis 9 anzeigt.

Zur Anzeige der Ergebnisse wurden zwei Arten von Tkinter-Etiketten und Druckanweisungen verwendet.

3.1. Programmcode (1)

tkinter_wo_threading.py


import tkinter as tk
from tkinter import ttk
from tkinter import font
import time

class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.pack()
        self.master.geometry("300x300")
        self.master.title("Tkinter Freezes after clicking Buttons")


        self.font_lbl_big = font.Font( family="Meiryo UI", size=30, weight="bold" )
        self.font_lbl_middle = font.Font( family="Meiryo UI", size=15, weight="bold" )
        self.font_lbl_small = font.Font( family="Meiryo UI", size=12, weight="normal" )

        self.create_widgets()

    def create_widgets(self):

        # Frame
        self.main_frame = tk.LabelFrame(self.master, text ='', font = self.font_lbl_small)
        self.main_frame.place(x=25,y=25)
        self.main_frame.configure(height = 250, width=250)
        self.main_frame.grid_propagate(0)
        self.main_frame.grid_columnconfigure(0, weight = 1)
       
        # Start Button
        self.btn_Start = ttk.Button( self.main_frame)
        self.btn_Start.configure( text='Start' )
        self.btn_Start.configure( command=self._main_func)
        self.btn_Start.grid( column=0, row=0,  pady=10 , sticky='NESW')

        # Label Title
        self.lbl_title = ttk.Label( self.main_frame)
        self.lbl_title.configure( text='Calculation Results Shown Here' )
        self.lbl_title.grid( column=0, row=1,  padx = 20, pady=20 ,sticky='EW')

        # Label Result
        self.lbl_result = ttk.Label( self.main_frame )
        self.lbl_result.configure( text='' )
        self.lbl_result.grid( column=0, row=2,  padx = 100, pady=10 ,sticky='EW')


    def _main_func(self):

        for i in range(10):
            print(i)
            self.lbl_result.configure(text = i, font = self.font_lbl_big)
            time.sleep(0.1)


def main():
    root = tk.Tk()
    app = Application(master=root)#Inherit
    app.mainloop()

if __name__ == "__main__":
    main()

3.2. Ausführungsergebnis

Lassen Sie uns diesen Code ausführen. Wenn Sie die Taste drücken, reagiert das Programm nicht mehr, bis die for-Anweisungsschleife endet. Die print-Anweisung druckt die Ergebnisse kontinuierlich aus, die GUI bleibt jedoch stationär. Und wenn die Schleife der for-Anweisung endet, wird nur die letzte Nummer angezeigt. Es ist nicht das, was Sie zuerst erwartet hatten.

Dies liegt daran, dass Python den Code zeilenweise ausführt. Wenn dies unverändert bleibt, ist die Antwort schlecht, da andere Ereignisse erst starten können, wenn ein Ereignis im GUI-Programm verarbeitet wird. with_thread.gif

4. Code, der Threading verwendet, um die Reaktionsfähigkeit zu verbessern

Zu diesem Zeitpunkt wird Threading verwendet. Informationen zum Einfädeln finden Sie im Referenzmaterial.

4.1 Programmiercode mit verbesserter Reaktionsfähigkeit (1)

Zuerst werden wir das Threading einführen.

import threading

Ändern Sie wiederum die Rückruffunktion der Schaltfläche in _start_thread (). Fügen Sie in diesem _start_thread () die Funktion ein, um _main_func () als Thread zu starten. Es ist ein Bild, das Sie als Ziel angeben und einen Start schreiben können.


def _start_thread(self):
        self.thread_main = threading.Thread(target = self._main_func)
        self.thread_main.start()

Der ganze Code.

tkinter_with_threading.py


import tkinter as tk
from tkinter import ttk
from tkinter import font
import time
import threading

class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.pack()
        self.master.geometry("300x300")
        self.master.title("Tkinter Freezes after clicking Buttons")


        self.font_lbl_big = font.Font( family="Meiryo UI", size=30, weight="bold" )
        self.font_lbl_middle = font.Font( family="Meiryo UI", size=15, weight="bold" )
        self.font_lbl_small = font.Font( family="Meiryo UI", size=12, weight="normal" )

        self.create_widgets()

    def create_widgets(self):

        # Frame
        self.main_frame = tk.LabelFrame(self.master, text ='', font = self.font_lbl_small)
        self.main_frame.place(x=25,y=25)
        self.main_frame.configure(height = 250, width=250)
        self.main_frame.grid_propagate(0)
        self.main_frame.grid_columnconfigure(0, weight = 1)

       
        # Start Button
        self.btn_Start = ttk.Button( self.main_frame)
        self.btn_Start.configure( text='Start' )
        self.btn_Start.configure( command=self._start_thread)
        self.btn_Start.grid( column=0, row=0,  pady=10 , sticky='NESW')

        # Label Title
        self.lbl_title = ttk.Label( self.main_frame)
        self.lbl_title.configure( text='Calculation Results Shown Here' )
        self.lbl_title.grid( column=0, row=1,  padx = 20, pady=20 ,sticky='EW')

        # Label Result
        self.lbl_result = ttk.Label( self.main_frame )
        self.lbl_result.configure( text='' )
        self.lbl_result.grid( column=0, row=2,  padx = 100, pady=10 ,sticky='EW')


    #-----------------------------------------------------------
    # Start Thread
    # -----------------------------------------------------------
    def _start_thread(self):
        self.thread_main = threading.Thread(target = self._main_func)
        self.thread_main.start()

    def _main_func(self):

        for i in range(10):
            print(i)
            self.lbl_result.configure(text = i, font = self.font_lbl_big)
            time.sleep(0.1)


def main():
    root = tk.Tk()
    app = Application(master=root)#Inherit
    app.mainloop()

if __name__ == "__main__":
    main()

4.2 Ausführungsergebnis

Dies ist das Ergebnis der Codeausführung mit Threading. without_thread.gif

Ich konnte bestätigen, dass das Programm wie ursprünglich beabsichtigt funktioniert. Das Programm reagiert schneller und kann andere Ereignisse verarbeiten.

Zusammenfassung

Ich konnte die Reaktionsfähigkeit des GUI-Programms mithilfe von Threads verbessern.

Referenzmaterial

1.python#Threading 2. Vollständiges Verständnis von Python-Threading und Multiprocessing 3. In [Python] -Thread implementieren

Recommended Posts

[Tkinter] Verbessern Sie die Reaktionsfähigkeit der Benutzeroberfläche
Einfache GUI App mit Tkinter Text
GUI-Erstellung in Python mit tkinter 2
Informationen zum Erstellen einer GUI mit TKinter of Python
Machen Sie GUI-Apps mit tkinter ganz einfach
Erstellen Sie eine GUI-App mit Tkinter of Python