为什么我必须在另一个 class 中创建我的线程以避免冻结我的 Tkinter UI?
Why do i have to create my thread in another class, to avoid freezing my Tkinter UI?
我有一个 Tkinter 应用程序,其中有一个调用函数的按钮。为避免冻结 UI,在此函数处理时,我在其自己的线程中启动它。
如果我在同一个 class 中生成线程,因为我正在调用的方法已定义,我的 UI 仍然会冻结。我能够解决此问题的唯一方法是创建 Threader class,其唯一目的是在新线程中调用函数。
我已经尝试将我的 app class 削减到仅相关的东西,以解决这个问题,但如果您怀疑我削减了,请告诉我太多了:
from threader import Threader
from threading import Thread
from tkinter import ttk
import tkinter as tk
class App(tk.Tk):
def __init__(self):
...
self.run_btn=ttk.Button(self, text='Run', command=self.start_clicked, width=15)
self.Threader = Threader()
...
def start_clicked(self):
Thread(target=self.my_func()).start() # this freezes my ui
# self.Threader.run_thread(self.my_func()) # this does not freeze my ui
def my_func(self):
# some logic
这是我的 Threader class:
from threading import Thread
class Threader:
def run_thread(self, name, func):
Thread(target=func).start()
在我的 App class 中,我已经包含了我尝试生成线程的两种方式,在 start_clicked 功能。第一个是冻结我的 UI 的那个,另一个是注释掉的,我在其中通过我的 Threader class 生成线程,是那个哪个没有。
在我看来,应该没有区别,所以我无法弄清楚为什么一个有效,另一个无效。
考虑这行代码:
Thread(target=self.my_func()).start()
功能上,和这个完全一样:
result = self.my_func()
Thread(target=result).start()
看到问题了吗?您正在当前线程中立即调用 self.my_func()
。
target
需要引用 函数:
Thread(target=self.my_func)
我有一个 Tkinter 应用程序,其中有一个调用函数的按钮。为避免冻结 UI,在此函数处理时,我在其自己的线程中启动它。
如果我在同一个 class 中生成线程,因为我正在调用的方法已定义,我的 UI 仍然会冻结。我能够解决此问题的唯一方法是创建 Threader class,其唯一目的是在新线程中调用函数。
我已经尝试将我的 app class 削减到仅相关的东西,以解决这个问题,但如果您怀疑我削减了,请告诉我太多了:
from threader import Threader
from threading import Thread
from tkinter import ttk
import tkinter as tk
class App(tk.Tk):
def __init__(self):
...
self.run_btn=ttk.Button(self, text='Run', command=self.start_clicked, width=15)
self.Threader = Threader()
...
def start_clicked(self):
Thread(target=self.my_func()).start() # this freezes my ui
# self.Threader.run_thread(self.my_func()) # this does not freeze my ui
def my_func(self):
# some logic
这是我的 Threader class:
from threading import Thread
class Threader:
def run_thread(self, name, func):
Thread(target=func).start()
在我的 App class 中,我已经包含了我尝试生成线程的两种方式,在 start_clicked 功能。第一个是冻结我的 UI 的那个,另一个是注释掉的,我在其中通过我的 Threader class 生成线程,是那个哪个没有。
在我看来,应该没有区别,所以我无法弄清楚为什么一个有效,另一个无效。
考虑这行代码:
Thread(target=self.my_func()).start()
功能上,和这个完全一样:
result = self.my_func()
Thread(target=result).start()
看到问题了吗?您正在当前线程中立即调用 self.my_func()
。
target
需要引用 函数:
Thread(target=self.my_func)