【问题标题】:Tkinter window does not load completelyTkinter 窗口未完全加载
【发布时间】:2020-08-29 19:25:31
【问题描述】:

我正在尝试创建一个显示进度的进度窗口,同时在后台执行任务。一切都按预期工作,除了窗口部分加载到屏幕上(它的多少取决于每次运行)。这是代码的相关部分:

def loading(): #Displays loading progress while setting up the exam
    global load, progress      
    load = Toplevel()
    load.title("Loading")
    load.attributes('-topmost', True)
    load.overrideredirect(True)
    lab = Label(load, text = ("Preparing Your Exam, Please Wait!\nPlease DO NOT Open any Other Window.\n"
                              +"Doing so may lead to immidiate Termination."))
    lab.grid(row = 0, column = 1, padx = 20, pady = 20)
    progress=Progressbar(load,orient=HORIZONTAL,length=200,mode='determinate')
    progress.grid(row = 1, column = 1, padx = 20, pady = 20)
    log = Label(load, image = logo)
    log.image = logo
    log.grid(row = 0, column = 0, rowspan = 2, padx = 20, pady = 20)
    w_req, h_req = load.winfo_width(), load.winfo_height()
    w_form = load.winfo_rootx() - load.winfo_x()
    w = w_req + w_form*2
    h = h_req + (load.winfo_rooty() - load.winfo_y()) + w_form
    x = (load.winfo_screenwidth() // 2) - (w // 2)
    y = (load.winfo_screenheight() // 2) - (h // 2)
    load.geometry(f'{w_req}x{h_req}+{x}+{y}')

调用loading后会发生以下情况:

loading()
conv_th = Thread(target = Convert).start()

Convert 函数转换和处理图像,我不分享它,因为它可能不相关。

在我看来,这可能是因为它没有足够的时间来完全加载,但我无法真正弄清楚是什么导致程序以这种方式运行。任何帮助将不胜感激!

更新:即使省略了conv_th = Thread(target = Convert).start(),也会出现这种行为,这意味着loading() 函数中可能存在问题。

【问题讨论】:

  • 尝试使用after 调用在 1 秒后开始处理,以便有时间完成加载。
  • @Mike67 感谢您的回复,但它似乎不起作用,我尝试了initial.after(1000, conv_th.start),但结果相同。我也尝试在最后从loading 函数中调用Thread,但没有区别。
  • 除非您的 Convert() 函数执行一些 I/O 或以其他方式足够频繁地释放 GIL(即它受计算限制),否则它可能会干扰 tkinter 的 mainloop()。您也许可以通过调用通用小部件方法 w.update_idletasks() 来缓解这种情况——这可以(也)通过 after() 方法进行调度。
  • @martineau 感谢您的快速回复,我会尝试一下,但我现在注意到了一些事情,即使我不调用转换,窗口也会部分打开。 loading() 函数内部有问题吗?
  • 这个conv_th = Thread(target = Convert).start() 是在按钮上实现的吗,因为如果是这样,您必须从start() 中删除(),否则它会自动启动

标签: python python-3.x multithreading tkinter tkinter-layout


【解决方案1】:

所以,我最终自己解决了这个问题。我说的是我认为最可能的原因,如果我给出的原因不正确或有其他解决方案,请纠正我。

这部分代码,

w_req, h_req = load.winfo_width(), load.winfo_height()
w_form = load.winfo_rootx() - load.winfo_x()
w = w_req + w_form*2
h = h_req + (load.winfo_rooty() - load.winfo_y()) + w_form
x = (load.winfo_screenwidth() // 2) - (w // 2)
y = (load.winfo_screenheight() // 2) - (h // 2)

在窗口完全加载之前执行得太早,因此在此之前加载的任何数量都被视为尺寸,然后设置值。

在上述部分代码解决问题之前添加命令load.update_idletasks()。感谢@martineau,您的评论对解决这个问题非常有帮助。

【讨论】:

  • 不客气……很高兴听到我的一个 cmets 被证明是有帮助的。
猜你喜欢
  • 1970-01-01
  • 2015-07-19
  • 2017-01-05
  • 2021-12-03
  • 1970-01-01
  • 2021-09-17
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多