Tkinter не может закрыть дополнительное окно

У меня открыто главное окно. Я не хочу закрывать это окно. (что, кажется, есть в большинстве этих вопросов).

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

Моя проблема в том, что когда я захожу в функцию из любого из вышеперечисленных действий, у меня нет ссылки на закрытие этого окна. как в «alt.destroy»

Я думаю использовать опцию перемещения мыши, поскольку она должна охватывать все потребности.

Вот пример кода того, что я пытаюсь сделать.

from tkinter import * 
backGd='#333333'
FrGd='white'
def AlignmentTypes():
    alt_x_y=ListWinStartPsn()       
    alt = Tk()
    alt.geometry(f"100x150+{alt_x_y[0]}+{alt_x_y[1]+20}")
    #alt.configure(bg=backGd)
    alt.bind("<Leave>", closeAltWin)

    Titlelabel=Label(alt, text = "Select Alignment Type",bg=backGd,fg=FrGd)
    alLeft_btn=Button(alt,text = "Align Left",fg = "Dark Blue",width=11)
    alCenter_btn=Button(alt,text = "Align Center",fg = "Dark Blue",width=11)
    alRight_btn=Button(alt,text = "Align Right",fg = "Dark Blue",width=11)
    alJustify_btn=Button(alt,text = "Align Justify",fg = "Dark Blue",width=11)
        
    Titlelabel.pack()
    alLeft_btn.pack()
    alCenter_btn.pack()
    alRight_btn.pack()
    alJustify_btn.pack()

def ListWinStartPsn():
    x, y = btn1.winfo_rootx(), btn1.winfo_rooty()
    return(x,y)

def closeAltWin(event):
    pass
    #alt.destroy

root = Tk()
root.title('Workopedia')
root.geometry('500x300')


frame1=Frame(root)
frame1.pack()
btn1=Button(frame1,text = "click",command=AlignmentTypes)
btn1.pack()
frame2=Frame(root)
frame2.pack()
lbl1=Label(frame1,text = "Stuff")
lbl1.pack()

root.mainloop()

Должно быть alt = Toplevel() вместо alt = Tk()

toyota Supra 16.06.2024 01:48
import * не является предпочтительным. Предпочтительны lower_case_names для функций и переменных. Подробнее см.: PEP 8 — Руководство по стилю кода Python
furas 16.06.2024 14:36
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
73
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Поэтому мне нужно было установить alt как глобальный

добавив глобальный alt в функцию AlignmentTypes(): как:

def AlignmentTypes():
        global alt

Теперь моя единственная проблема в том, что она закрывается после того, как в окне остается какой-либо виджет. Я хочу, чтобы это было только при выходе из окна.

Если у кого-то есть идеи по этому поводу, я все равно буду признателен

Это должно быть либо изменение вашего текущего вопроса, либо опубликование как новый вопрос со ссылкой на этот вопрос для контекста (если применимо. SO работает немного иначе, чем другие сайты, у него нет тем. Только один вопрос на каждый). пост. Спасибо.

L Tyrone 17.06.2024 09:58

когда я нажимаю на кнопку, под мышкой открывается маленькое окошко позиция. Я хочу, чтобы это второе окно закрывалось, когда одно из его кнопки нажаты или после того, как мышь отошла.

Проблема может быть решена.

В строке 6 измените alt = Tk() на: alt = Toplevel()

В функцию closeAltWin добавьте это root.winfo_children()

Фрагмент:

def closeAltWin(event):
    for widget in root.winfo_children():
        if isinstance(widget, Toplevel):
            widget.destroy()

Я думаю использовать опцию перемещения мыши, поскольку она должна закрывать все потребности.

Как видите, мышь отодвинулась. Уничтожит второе окно.

Скриншот:

Ответ принят как подходящий

Закрытие второго окна при выходе из него невозможно, поскольку это поведение по умолчанию. Но когда второе окно открыто, если вы войдете в первое окно, второе окно может закрыться.

Разница между двумя вышеперечисленными заключается в том, что выход из второго окна означает (или выход из любого окна), когда второе окно открыто, когда вы переключаетесь на любую другую программу на вашем компьютере (с помощью alt + tab или с помощью мыши). второе окно. Это происходит потому, что: Когда вы работаете во втором окне, вдруг, если вам позвонят и вы захотите перейти на новую программу на своем компьютере, чтобы просмотреть детали, вы не сможете сохранить и закрыть окно, перейдите к другому. окно и возвращайся. Таким образом, оно спроектировано таким образом, что окно не может быть закрыто без каких-либо действий со стороны пользователя.

Вход в первое окно почти аналогичен выходу из второго окна. Единственное, если подвести мышку к первому окну, то когда второе окно открыто, второе окно закроется. Единственное: если вы переместите указатель мыши в другое место рабочего стола, а не в первое окно, то второе окно не закроется.

Следующий код закроет второе окно, если вы нажмете любую кнопку во втором окне или войдете в первое окно.

from tkinter import * 
backGd='#333333'
FrGd='white'

# declaring a dict as I don't want to declare root as global variable
dct = {}
def AlignmentTypes():

    # we already defined as dct['window'] is root. But giving a variable name for dct['window']
    # Let the name of the variable be 'root' again for the sake of convenience.
   
    root = dct['window']  

    #The functions are defined in the second window so that these functions can be accessed by 2nd window.
    def close_window(*event):
    
        #Unbind root with '<Enter>'  to avoid error while moving the mouse to root window after the 2nd window is closed        
        root.bind('<Enter>', lambda e:'break')
        
        #Close the second winsow
        alt.destroy()
        
    # This function also defned inside the second window as it is used in 2nd window    
    def ListWinStartPsn():
        x, y = btn1.winfo_rootx(), btn1.winfo_rooty()
        return(x,y)
    
    alt_x_y=ListWinStartPsn()       
    alt = Tk()
    alt.geometry(f"100x150+{alt_x_y[0]}+{alt_x_y[1]+20}")
    #alt.configure(bg=backGd)
    
    # map all the buttons with the function close_window
    Titlelabel=Label(alt, text = "Select Alignment Type",bg=backGd,fg=FrGd)
    alLeft_btn=Button(alt,text = "Align Left",fg = "Dark Blue",width=11, command = close_window)
    alCenter_btn=Button(alt,text = "Align Center",fg = "Dark Blue",width=11, command = close_window)
    alRight_btn=Button(alt,text = "Align Right",fg = "Dark Blue",width=11, command = close_window)
    alJustify_btn=Button(alt,text = "Align Justify",fg = "Dark Blue",width=11, command = close_window)
        
    Titlelabel.pack()
    alLeft_btn.pack()
    alCenter_btn.pack()
    alRight_btn.pack()
    alJustify_btn.pack()
    
    # Bind root, <Enter> with the function close_window.
    root.bind('<Enter>', close_window)  

root = Tk()
root.title('Workopedia')
root.geometry('500x300')

# to avoid global vaiable, make root as a value of the dict
dct['window'] = root


frame1=Frame(root)
frame1.pack()
btn1=Button(frame1,text = "click",command=AlignmentTypes)
btn1.pack()
frame2=Frame(root)
frame2.pack()
lbl1=Label(frame1,text = "Stuff")
lbl1.pack()

root.mainloop()

Спасибо, отлично, я ценю вклад каждого

RJTTAZ 17.06.2024 21:47

Вы можете проверить, является ли виджет, вызывающий событие <Leave>, верхним уровнем, если да, то уничтожьте виджет:

def closeAltWin(event):
    if event.widget.winfo_toplevel() is event.widget:
        # the widget that triggers the event is a toplevel window
        # so destroy it
        event.widget.destroy()

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

Другие вопросы по теме