Предисловие

Tkinter (интерфейс Tk) — это модуль стандартного набора инструментов Python Tk GUI. Tk и Tkinter работают на большинстве платформ Unix, но также могут использоваться в системах Windows и Macintosh. последующие версии Tk8.0 могут использоваться для реализации собственных оконных стилей и хорошо работают на большинстве платформ. Python использует Tkinter для быстрого создания приложений с графическим интерфейсом. Поскольку Tkinter встроен в установщик Python, вы можете импортировать библиотеку Tkinter после установки Python, а поскольку IDLE написан на Tkinter, Tkinter может работать с простыми графическими интерфейсами.

I. Описание проблемы
Если при запуске программы Python с графическим интерфейсом пользователя нажать кнопку для запуска требующей много времени операции, интерфейс зависнет и покажет, что он не отвечает, что сделает невозможным работу с другими компонентами.

II. идея решения
Используйте поток для выполнения функции события кнопки привязки, чтобы реализовать работу без задержек и устранить застревание интерфейса.

III. Пример кода

1. Поточный метод выполнения функции события кнопки привязки

import threading
def thread_it(func, *args):
    """ Packing functions into threads """
    self.myThread = threading.Thread(target=func, args=args)
    self.myThread.setDaemon(True)  # When the main thread exits, the sub-threads exit directly after it, regardless of whether they finish running or not.
    self.myThread.start()

2. Полный код

import sys
import time
import tkinter as tk
from tkinter.messagebox import askyesno
from tkinter.scrolledtext import ScrolledText
import threading


class TestGui(object):
    def __init__(self, init_window_name):
        self.init_window_name = init_window_name
        self.init_window_name.title("Packing the button method into a thread to run a non-lagging test")  # Setting the window title
        self.init_window_name.geometry('700x350')  # Setting the window size
        """ Click on the upper right corner to close the form popup event """
        self.init_window_name.protocol('WM_DELETE_WINDOW', lambda: self.thread_it(self.clos_window))
        """ Component Container Creation"""
        self.log_frame = tk.Frame(self.init_window_name)  # Creating a Container to Hold Logging Components
        self.log_frame.grid(padx=20, pady=0, row=1, column=0, sticky=tk.W)
        self.runs_button_frame = tk.Frame(self.init_window_name)  # Creating a Container to Hold Logging Components
        self.runs_button_frame.grid(padx=20, pady=0, row=2, column=0, sticky=tk.W)
        """ logframe """
        self.run_log = ScrolledText(self.log_frame, font=('SimHei', 13), width=69, height=17)
        self.run_log.grid(padx=20, pady=5, row=0, column=0)
        """ operate buttons """
        self.start_run1 = tk.Button(self.runs_button_frame, text='begin print 1', font=('SimHei', 15, 'bold'), fg="white", bg="#1E90FF", width=25, command=lambda: self.thread_it(self.print1))
        self.start_run1.grid(padx=20, pady=0, row=0, column=1)
        self.start_run2 = tk.Button(self.runs_button_frame, text='begin print 2', font=('SimHei', 15, 'bold'), fg="white", bg="#1E90FF", width=25, command=lambda: self.thread_it(self.print2))
        self.start_run2.grid(padx=35, pady=0, row=0, column=2)

    def thread_it(self, func, *args):
        """ Packing functions into threads """
        self.myThread = threading.Thread(target=func, args=args)
        self.myThread .setDaemon(True)  # When the main thread exits, the sub-threads exit directly after it, regardless of whether they finish running or not.
        self.myThread .start()

    def print1(self):
        for i in range(100):
            tip_content = f'{i}th print - I am hero'
            self.run_log_print(message=tip_content)
            time.sleep(0.1)  # sleep
        self.run_log_print(message='I am hero 1 - print done')

    def print2(self):
        for i in range(100, 200):
            tip_content = f'{i}th print - I am hero 2'
            self.run_log_print(message=tip_content)
            time.sleep(0.05)  # sleep
        self.run_log_print(message='I am hero 2 - print done')

    def run_log_print(self, message):
        self.run_log.config(state=tk.NORMAL)
        self.run_log.insert(tk.END, "\n" + message + "\n")
        self.run_log.see(tk.END)
        self.run_log.update()
        self.run_log.config(state=tk.DISABLED)

    def clos_window(self):
        ans = askyesno(title='Hero v1.1 warning', message='Are you sure to exit the program?\nYes to exit, otherwise continue!')
        if ans:
            self.init_window_name.destroy()
            sys.exit()
        else:
            return None


if __name__ == '__main__':
    """ Packing the button method into a thread to run without lagging """
    """ Instantiate a parent window """
    init_window = tk.Tk()
    """ set tk interface top """
    init_window.attributes("-topmost", 1)
    """ Creating a Gui Class Object """
    test_gui = TestGui(init_window)
    """ Initializing GUi Components """
    init_window.mainloop()