Heute werde ich erklären, wie Threading verwendet wird, um die Reaktionsfähigkeit beim Erstellen einer GUI-Anwendung zu verbessern.
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. Schreiben wir den Code sofort in Tkinter.
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.
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()
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.
Zu diesem Zeitpunkt wird Threading verwendet. Informationen zum Einfädeln finden Sie im Referenzmaterial.
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()
Dies ist das Ergebnis der Codeausführung mit Threading.
Ich konnte bestätigen, dass das Programm wie ursprünglich beabsichtigt funktioniert. Das Programm reagiert schneller und kann andere Ereignisse verarbeiten.
Ich konnte die Reaktionsfähigkeit des GUI-Programms mithilfe von Threads verbessern.
1.python#Threading 2. Vollständiges Verständnis von Python-Threading und Multiprocessing 3. In [Python] -Thread implementieren
Recommended Posts