【问题标题】:Tkinter destroy TopLevel window and create a new one in its place with one buttonTkinter 销毁 TopLevel 窗口并使用一个按钮在其位置创建一个新窗口
【发布时间】:2020-07-21 00:10:56
【问题描述】:

目前我正在尝试销毁顶层窗口(如果它在那里,如果不创建它)并在其位置生成一个新窗口。

当前创建窗口的按钮会创建一个带有标签的小窗口,该窗口仅显示基于 GUI 上用户输入的命令行。

但是,我尝试了谷歌搜索和大量不同的方法,但我无法让它破坏窗口并创建一个新窗口。

def view_command():  # Views Command
    cmd_line_window = Toplevel()
    cmd_line_window.title('Command Line')
    cmd_line_window.configure(background="#434547")

    #doing stuff here#

    cmd_label = Label(cmd_line_window, text=example_cmd_output, foreground="white",
                      background="#434547")
    cmd_label.config(font=("Helvetica", 16))
    cmd_label.pack()

btn = Button(root, text="Click Me", command=view_command)

我尝试了一些if 语句,一些try 语句,但我似乎无法让它正常工作。我觉得有一种简单的方法可以在一个函数中执行此操作,但是我似乎无法理解。

编辑:目前,每次我单击按钮时,它都会更新我选择的所有变量并显示正确的内容,它只会不断生成更多带有更新标签的窗口。

Edit2:我使用了来自 cmets 的建议和底部的答案,以获得两全其美的效果。这是我的代码,它会打开一个窗口或根据窗口是否已经打开来更新标签!

def view_command():
    global cmd_label
    example_cmd_output = acodec_stream_choices[acodec_stream.get()] \
                     + encoder_dropdownmenu_choices[encoder.get()] + \
                     acodec_bitrate_choices[acodec_bitrate.get()] + \
                     acodec_channel_choices[acodec_channel.get()] + \
                     acodec_samplerate_choices[acodec_samplerate.get()] + \
                     acodec_gain_choices[acodec_gain.get()] + ac3_custom_cmd_input + ac3_title_input
    try:
        cmd_label.config(text=example_cmd_output)
    except (AttributeError, NameError):
        cmd_line_window = Toplevel()
        cmd_line_window.title('Command Line')
        cmd_line_window.configure(background="#434547")
        cmd_label = Label(cmd_line_window, text=example_cmd_output, foreground="white", background="#434547")
        cmd_label.config(font=("Helvetica", 16))
        cmd_label.pack()

    btn = Button(root, text="Click Me", command=view_command)

【问题讨论】:

  • 在当前Toplevel 实例上调用.destroy() 方法。
  • 您想破坏Toplevel() 并创建一个新的吗?或者当按下按钮时,你想检查是否存在任何顶层然后删除所有现有的顶层?你能解释一下吗
  • 你可以只更新标签文本而不是破坏和创建窗口吗?
  • @CoolCloud 是的,我有一个窗口,有几个下拉菜单等,一旦用户完成他们的选择,就会有一个按钮允许他们查看他们选择的命令行。当他们按下此按钮时,会打开一个窗口,其中包含基于他们选择的标签。如果他们更改设置并再次按下它,我希望它删除那里的窗口并打开一个新窗口。 acw1668 我想这可以正常工作,只要它首先打开带有标签的小窗口并在每次按下时更新标签。它需要检查窗口是否在那里,如果没有打开它。

标签: python tkinter tk


【解决方案1】:

正如我在评论中提到的,您可以调用通用小部件destroy() 方法来删​​除任何可能已经存在的当前Toplevel。但是,由于您没有发布自己的代码来尝试这样做(但没有工作),所以这里有一个可运行的示例:

import tkinter as tk


def view_command():  # Views Command
    global cmd_line_window

    try:
        cmd_line_window.destroy()
    except (AttributeError, NameError):
        pass

    cmd_line_window = tk.Toplevel()
    cmd_line_window.title('Command Line')
    cmd_line_window.configure(background="#434547")

    #doing stuff here#

    cmd_label = tk.Label(cmd_line_window, text=example_cmd_output, foreground="white",
                         background="#434547")
    cmd_label.config(font=("Helvetica", 16))
    cmd_label.pack()


example_cmd_output = 'example cmd output'
root = tk.Tk()
btn = tk.Button(root, text="Click Me", command=view_command)
btn.pack()
root.mainloop()

更新

正如 @acw1668 和我在其他 cmets 中提到的,更好的方法是只创建 Toplevel 窗口和 Label 一次,然后更新文本Label(而不是每次点击 Button 时都销毁和重新创建所有内容。同样,try/except 用于轻松实现此目的:

import tkinter as tk


def view_command():  # Views Command
    global cmd_line_window
    global cmd_label

    #doing stuff here#
    example_cmd_output = 'example cmd output'

    try:
        cmd_label.config(text=example_cmd_output)  # Update Label's text.
    except (NameError, tk.TclError):  # Label or Toplevel widget doesn't exist.
        cmd_line_window = tk.Toplevel()
        cmd_line_window.title('Command Line')
        cmd_line_window.configure(background="#434547")
        cmd_label = tk.Label(cmd_line_window, font=("Helvetica", 16),
                             foreground="white", background="#434547",
                             text=example_cmd_output)
        cmd_label.pack()


root = tk.Tk()
btn = tk.Button(root, text="Click Me", command=view_command)
btn.pack()
root.mainloop()

【讨论】:

  • 我是个白痴,我把这部分代码“try: cmd_line_window.destroy() except (AttributeError, NameError): pass”放在了导致错误的错误位置。我感谢详细的回复和解决方案。我仍然无法投票,但我确实将其标记为已接受的解决方案!
  • 我确实以这种方式使用它。完美运行!感谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多