如何使 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
...