Почему я получаю дополнительное пустое окно в Tkinter?

#python #tkinter #window #toplevel

#python #tkinter #окно #верхний уровень

Вопрос:

Вот мой код:

 from tkinter import *

OPTIONS = ["Available","Busy","Invisible","Away"]

now = Toplevel()
variable = StringVar(now)
variable.set(OPTIONS[0]) # default value
details = {"U_status":""}
def verify():
    global u_status
    details["U_status"]=variable.get()
    print ("value is:"   variable.get())
    now.destroy()
def status():
    w = OptionMenu(now, variable, *OPTIONS)
    w.pack()
    button = Button(now, text="OK", command=verify, relief='flat')
    button.pack()
if __name__=='__main__':
    status()
    mainloop()
  

При выполнении приведенного выше кода вместе с окном (которое я хотел) появляется другое пустое окно. Кто-нибудь может понять, что не так в этом коде?

Ответ №1:

Здесь now = Toplevel() должно быть заменено на Tk() , например:

 now = Tk()
  

При использовании Toplevel() Tk() окно создается в фоновом режиме, если оно еще не создано (ваш случай), и именно по этой причине вы получаете пустое новое окно. На самом деле это пустое окно — ваше главное окно.

Toplevel() используется для создания дочерних окон для родительских Tk() окон, то есть, если вы хотите, чтобы дополнительные окна находились в вашем главном окне ( now ), вы будете использовать Toplevel() . Потому что более одного Tk() в вашем коде позже вызовет некоторые ошибки.

Комментарии:

1. Но, как только я это сделаю, я столкнусь с ошибками при удалении окна с помощью .destroy()

2. @CodeCarbonate now.destroy() уничтожит главное окно, в вашем случае просто нажмите кнопку, и оно должно уничтожить окно.

3. Предположим, я называю переменную с именем now и устанавливаю для нее значение Tk() , если я хочу удалить только главное окно и сохранить другие части программы, я использую now.destroy() . Но я получаю сообщение об ошибке.

4. Какую другую часть программы вы имеете в виду? Уничтожение a Tk() уничтожит все приложение.

5. Точно так же, как сброс значения now в Tk() и отображение того же окна с другим содержимым после уничтожения now .

Ответ №2:

Пустое окно на самом деле является корневым окном вашего приложения, которое tkinter создает по умолчанию. Вероятно, вы хотите быть явным, создать tk.Tk() корневой каталог и сохранить ссылку на него.

Новые окна могут создаваться и уничтожаться на досуге; ваше приложение будет продолжать существовать до тех пор, пока вы сохраняете root активным.

Может быть, что-то вроде этого:

 import tkinter as tk


def verify():
    now = tk.Toplevel(root)
    details["U_status"] = variable.get()
    txt = f'value is: {details["U_status"]}'
    tk.Label(now, text=txt).pack()
    now.after(3000, now.destroy)
    
def status():
    tk.OptionMenu(root, variable, *OPTIONS).pack()
    tk.Button(root, text="OK", command=verify, relief='flat').pack()
    
    
if __name__=='__main__':
    
    OPTIONS = ["Available", "Busy", "Invisible", "Away"]
    
    root = tk.Tk()
    variable = tk.StringVar(root)
    variable.set(OPTIONS[0])
    details = {"U_status": ""}
    status()
    root.mainloop()
  

Комментарии:

1. Но когда я запускаю приведенный вами код, возникает ошибка с указанием NameError: name ‘mainloop’ не определено

2. Да, это должно быть root.mainloop() , извините, моя ошибка — я исправил это.