如何使 Python Tkinter GUI 检查其他线程是否已完成 GUI 更改?
How to make Python Tkinter GUI checks if an other thread has finished to make GUI changes?
我正在尝试在 Tkinter 中使用多线程。我有一个按钮,允许用户使用文件选择器选择 .xlsx 文件,然后将其发送到数据库。数据库响应数据框对象,然后通过树视图显示给用户。
我有一个函数File_Dialog(treeview)
,就是用于这个目的。当我得到文件路径时,我使用不同的线程将文件路径发送到数据库。
class databaseGetDF(Thread):
def __init__(self,filepath):
super().__init__()
self.filepath = filepath
self.df = None
def run(self):
self.df = db.addCollectionData(self.filepath,True)
在我的 File_Dialog(treeview)
中,我这样做,
download_thread = databaseGetDF(filename)
download_thread.start()
# I want to check now if my thread has finished
while download_thread.is_alive:
print("thread alive")
df = download_thread.df
然后,我使用树视图显示 DF。问题是 while 循环导致我的 GUI 在线程完成之前变得无响应。如果我不使用 while 循环,数据库会在一个单独的循环中更新,但 GUI 不会,因为它不等待线程 return 一个数据帧。
关于我的框架结构,我使用的是notebook tkinter结构。我有一个打开文件对话框的按钮。
def configureHomeFrame(frame):
importButton = Button(frame, text='IMPORT DATASET (XLSX)', command=lambda: File_dialog(treeView), height=5,
width=35,
bg='#bdbdbd')
frame属性为笔记本边框。
谢谢。
你可以使用.wait_variable()
函数来代替while循环因为.wait_variable()
不会阻塞tkintermainloop()
:
- 创建一个 tkinter 变量:
var1 = StringVar()
- 将此变量传递给
databaseGetDF
class
- 调用
.wait_variable(var1)
而不是 while 循环
- 线程任务完成时更新此变量
示例:
class databaseGetDF(Thread):
def __init__(self, filepath, notify_var):
super().__init__()
self.filepath = filepath
self.notify_var = notify_var
self.df = None
def run(self):
self.df = db.addCollectionData(self.filepath, True)
# update self.notify_var
self.notify_var.set('')
...
# create a tkinter variable
var1 = StringVar()
# pass the variable to databaseGetDF class
download_thread = databaseGetDF(filename, var1)
download_thread.start()
# wait for the thread completes
root.wait_variable(var1) # assume root is the root window
# thread completed, so you can get the dataframe
df = download_thread.df
...
我正在尝试在 Tkinter 中使用多线程。我有一个按钮,允许用户使用文件选择器选择 .xlsx 文件,然后将其发送到数据库。数据库响应数据框对象,然后通过树视图显示给用户。
我有一个函数File_Dialog(treeview)
,就是用于这个目的。当我得到文件路径时,我使用不同的线程将文件路径发送到数据库。
class databaseGetDF(Thread):
def __init__(self,filepath):
super().__init__()
self.filepath = filepath
self.df = None
def run(self):
self.df = db.addCollectionData(self.filepath,True)
在我的 File_Dialog(treeview)
中,我这样做,
download_thread = databaseGetDF(filename)
download_thread.start()
# I want to check now if my thread has finished
while download_thread.is_alive:
print("thread alive")
df = download_thread.df
然后,我使用树视图显示 DF。问题是 while 循环导致我的 GUI 在线程完成之前变得无响应。如果我不使用 while 循环,数据库会在一个单独的循环中更新,但 GUI 不会,因为它不等待线程 return 一个数据帧。
关于我的框架结构,我使用的是notebook tkinter结构。我有一个打开文件对话框的按钮。
def configureHomeFrame(frame):
importButton = Button(frame, text='IMPORT DATASET (XLSX)', command=lambda: File_dialog(treeView), height=5,
width=35,
bg='#bdbdbd')
frame属性为笔记本边框。
谢谢。
你可以使用.wait_variable()
函数来代替while循环因为.wait_variable()
不会阻塞tkintermainloop()
:
- 创建一个 tkinter 变量:
var1 = StringVar()
- 将此变量传递给
databaseGetDF
class - 调用
.wait_variable(var1)
而不是 while 循环 - 线程任务完成时更新此变量
示例:
class databaseGetDF(Thread):
def __init__(self, filepath, notify_var):
super().__init__()
self.filepath = filepath
self.notify_var = notify_var
self.df = None
def run(self):
self.df = db.addCollectionData(self.filepath, True)
# update self.notify_var
self.notify_var.set('')
...
# create a tkinter variable
var1 = StringVar()
# pass the variable to databaseGetDF class
download_thread = databaseGetDF(filename, var1)
download_thread.start()
# wait for the thread completes
root.wait_variable(var1) # assume root is the root window
# thread completed, so you can get the dataframe
df = download_thread.df
...