Python 如何从另一个线程中的Flask应用程序更新tkinter窗口中的进度条值?

Python 如何从另一个线程中的Flask应用程序更新tkinter窗口中的进度条值?,python,multithreading,flask,tkinter,multiprocessing,Python,Multithreading,Flask,Tkinter,Multiprocessing,我有一个Flask应用程序,可以在数据库中插入一些数据。在插入过程中,我需要一个进度条来显示插入了多少数据(因此,我使用determinate模式)。知道Flask和tkinter不能很好地结合在一起,我决定在一个单独的线程中显示tkinter窗口,主线程是Flask应用程序 这是到目前为止我的代码 import tkinter as tk from multiprocessing import Process from tkinter.ttk import Progressbar, Butto

我有一个
Flask
应用程序,可以在数据库中插入一些数据。在插入过程中,我需要一个进度条来显示插入了多少数据(因此,我使用
determinate
模式)。知道
Flask
tkinter
不能很好地结合在一起,我决定在一个单独的线程中显示
tkinter
窗口,主线程是
Flask
应用程序

这是到目前为止我的代码

import tkinter as tk
from multiprocessing import Process
from tkinter.ttk import Progressbar, Button

import global_library
from application import config
from application.admin import add_match as a
from application.xml import create_string as cs
from application.xml import dl_xml_file as dl
from application.xml import xml_parsing as xp

def show_progress_window(low_end, high_end, match_count):
    root = tk.Tk()
    progress_bar = Progressbar(root, mode='determinate', orient='horizontal', length=200)
    progress_bar['maximum'] = high_end - low_end
    progress_bar['value'] = match_count
    progress_bar.pack()
    cancel_button = Button(root, text='Anulare')
    cancel_button.pack()
    root.mainloop()


def import_engine(low_end, high_end):
    file = config['DEFAULT']['PROTECTED_RESOURCE_PATH']
    for match_id in range(low_end, high_end + 1, 1):
        p = Process(target=show_progress_window, args=(low_end, high_end, match_id - low_end))
        p.start()
        p.join()
        params = cs.create_match_details_string(match_id)
        dl.download_xml_file(file, params, global_library.details_savepath)
        match_details = xp.parse_match_details_file(match_id)
        a.add_a_match(match_details[0], match_details[1], match_details[2], match_details[3], match_details[4],
                      match_details[5], match_details[6], match_details[7], match_details[8], match_details[9],
                      match_details[10], match_details[11], match_details[12], match_details[13], match_details[14],
                      match_details[15], match_details[16])
当我运行此部件时,进度条会更新,但我必须手动关闭窗口才能开始导入。每次导入后,将显示窗口,其中进度条显示。。。进步。显然,这是来自
mainloop()
。很明显,我不能支持这种方法

我错在哪里了?我应该怎么做,因为我不必在每次迭代时手动关闭窗口


稍后编辑:一个非常重要的事实是
tkinter
必须在主线程中运行。如果没有,无论发生什么情况,进度条都不会更新。

好的,我的第一个答案毫无意义。您是否尝试过将主循环从函数中删除。因为现在每次调用进度条时,它都会创建一个新的tk()实例

比如:

root = tkinter.Tk()
# call your function and pass "root" to it as well
root.mainloop()
编辑1: 下面的代码提供了两个函数,说明您似乎可以通过启动新的主循环来“更新”tkinter。但事实并非如此

import tkinter as tk

def looptk(min,max,progress):
    root=tk.Tk()
    label = tk.Label(root, text=progress).pack()
    root.mainloop()
    print(id(root))


def looptk2(min,max,progress,root):
    label = tk.Label(root, text=progress).pack()
    print(id(root))

min = 0
max = 6
i = 0

while i < max:
    looptk(1,5,i)
    i += 1

root=tk.Tk()
min = 0
max = 6
i = 0
while i < max:
    looptk2(1,5,i,root)
    i += 1
root.mainloop()
要修复它,您需要在for循环之前创建一个mainloop。将其更改为以下内容:

root = tk.tk()
for match_id in range(low_end, high_end + 1, 1):
    p = Process(target=show_progress_window, args=(low_end, high_end, match_id - low_end,root))

root.mainloop()
不要忘记在函数
show\u progress\u窗口的括号之间添加“root”(将root添加到末尾)

并从函数中删除主循环。

我应该已经在ttk progressbar上读到了。我认为它可以像其他小部件一样工作,现在它有了意义。这听起来好像progressbar无法完成。我怀疑您需要将
进度条['maximum']=高端-低端
更改为
进度条['maximum']=高端-低端-1
。无论如何,检查变量是否到达进度条的末尾。
progress\u bar['value']
在运行时是否增加?我认为您仍然在创建几个主循环。我提供了一个小样本来说明我的答案中的要点。将
print(id(root))
添加到
root.mainloop()
之后的代码中。如果您获得了不同的ID,那么您就有了一个新的主循环。谢谢您的帮助。它不起作用有一个隐藏的原因。我消除了它,它工作得很好。
root = tk.tk()
for match_id in range(low_end, high_end + 1, 1):
    p = Process(target=show_progress_window, args=(low_end, high_end, match_id - low_end,root))

root.mainloop()