【问题标题】:Closing a Tkinter popup automatically without closing the main window自动关闭 Tkinter 弹出窗口而不关闭主窗口
【发布时间】:2021-06-25 00:27:43
【问题描述】:

我正在为一个项目制作 GUI,我的主管要求我包含一个进度条,因为程序的每次迭代可能需要 7 分钟。

我希望进度条在单独的窗口中弹出,并在进程完成后关闭,但根据我目前的理解,要么我必须手动关闭弹出窗口,要么立即关闭整个 GUI。

这是我正在使用的代码的简化版本

import Tkinter as tk
from ttk import Progressbar
from os import listdir
import threading
import time
root = tk.Tk()
root.title("TCC Image Processing")



def create_tcc(input_bar, input_progress_dialog):


    input_bar['maximum'] = 5
    input_bar['value'] = 0
    for x in range(5):
        time.sleep(1)
        input_bar['value'] += 1
    # this line is where the touble seems to be
    input_progress_dialog.destroy()


def run_tcc():
    progress_dialog = tk.Toplevel()
    progress_dialog.title("TCC Processing")

    bar = Progressbar(progress_dialog, orient="horizontal", length=500, value=0, mode="determinate")
    bar.grid(row=4, columnspan=2)
    t = threading.Thread(target=create_tcc, args=(bar, progress_dialog))
    t.start()
tcc_run_button = tk.Button(root, text="RUN", command=lambda:run_tcc())
tcc_run_button.pack()

root.mainloop()

如果可能的话,我想避免下载直接 python 不附带的额外模块。

【问题讨论】:

  • 除此之外:全球名称rootrun_tcc.root2create_tcc.root 的相似性令人困惑。由于两个局部变量实际上都没有引用应用程序的主窗口,因此可以选择另一个变量名称,例如 progress_dialog?
  • 您的代码,以其当前编辑的形式,非常适合我。你现在到底有什么问题?
  • 上面的代码运行,当我点击按钮时,会出现一个带有进度条的弹出窗口。杠铃走四步,然后停止,当它应该走五步时。唯一一次它使用当前版本的代码执行了 5 次程序崩溃,并出现一个新的弹出窗口,提示遇到问题。
  • 我认为程序崩溃是因为tkinter 是单线程的,而您正试图将其放入两个线程中

标签: python user-interface tkinter


【解决方案1】:

任务完成后拨打.destroy()progress_dialog

progress_dialog.destroy()

这将安全地退出弹出窗口,而不会杀死整个应用程序。

【讨论】:

  • 对我来说,使用 .destroy() 会导致进度条加载到 80%,然后停止并保持打开状态。
【解决方案2】:

对不起,necro,但我遇到了这个并找到了答案,并想分享以防其他人遇到它。

在进度条达到其 5 秒生命周期的确切时刻,窗口关闭。条确实加载到 100%,您可能需要录制并放慢速度,但它肯定会达到 100%。问题在于,由于窗口在被破坏的完全相同的毫秒内达到 100%,所以看起来它没有成功。

在您的 input_progress_dialog.destroy() 之前添加 time.sleep(.5) 可以修复感知到的故障点。

以下代码适用于 Python 2,对于 3,将 import Tkinter as tk 更改为 import tkinter as tkfrom ttk import Progressbar 更改为 from tkinter.ttk import Progressbar

import Tkinter as tk
from ttk import Progressbar
from os import listdir
import threading
import time
root = tk.Tk()
root.title("TCC Image Processing")



def create_tcc(input_bar, input_progress_dialog):


    input_bar['maximum'] = 5
    input_bar['value'] = 0
    for x in range(5):
        time.sleep(1)
        input_bar['value'] += 1
    # this fixes it
    time.sleep(.5)
    input_progress_dialog.destroy()


def run_tcc():
    progress_dialog = tk.Toplevel()
    progress_dialog.title("TCC Processing")

    bar = Progressbar(progress_dialog, orient="horizontal", length=500, value=0, mode="determinate")
    bar.grid(row=4, columnspan=2)
    t = threading.Thread(target=create_tcc, args=(bar, progress_dialog))
    t.start()
tcc_run_button = tk.Button(root, text="RUN", command=lambda:run_tcc())
tcc_run_button.pack()

root.mainloop()

【讨论】:

  • 我认为程序崩溃是因为tkinter 是单线程的,而您正试图将其放入两个线程中。无论如何,在 python 3.x 上它对我来说不会崩溃
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
相关资源
最近更新 更多