Как мне обработать событие закрытия окна в Tkinter? - PullRequest
96 голосов
/ 21 сентября 2008

Как мне обработать событие закрытия окна (пользователь нажимает кнопку «X») в программе Python Tkinter?

Ответы [ 4 ]

129 голосов
/ 21 сентября 2008

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

Вы можете использовать метод protocol для установки обработчика для этого протокола (виджет должен быть виджетом Tk или Toplevel):

Вот вам конкретный пример:

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()

def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        root.destroy()

root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
21 голосов
/ 11 февраля 2013

Мэтт показал одну классическую модификацию кнопки закрытия.
Другой - чтобы кнопка закрытия свернула окно.
Вы можете воспроизвести это поведение, используя метод iconify
быть протоколом вторым аргументом метода.

Вот рабочий пример, протестированный на Windows 7:

# Python 3
import tkinter
import tkinter.scrolledtext as scrolledtext

class GUI(object):

    def __init__(self):
        root = self.root = tkinter.Tk()
        root.title('Test')

    # make the top right close button minimize (iconify) the main window
        root.protocol("WM_DELETE_WINDOW", root.iconify)

    # make Esc exit the program
        root.bind('<Escape>', lambda e: root.destroy())

    # create a menu bar with an Exit command
        menubar = tkinter.Menu(root)
        filemenu = tkinter.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=root.destroy)
        menubar.add_cascade(label="File", menu=filemenu)
        root.config(menu=menubar)

    # create a Text widget with a Scrollbar attached
        txt = scrolledtext.ScrolledText(root, undo=True)
        txt['font'] = ('consolas', '12')
        txt.pack(expand=True, fill='both')

gui = GUI()
gui.root.mainloop()

В этом примере мы даем пользователю две новые опции выхода:
классическое файловое меню -> Выход, а также кнопка Esc .

3 голосов
/ 12 апреля 2018

В зависимости от активности Tkinter, end esp. при использовании Tkinter.after остановка этого действия с помощью destroy() - даже с использованием protocol (), кнопки и т. д. - нарушит это действие (ошибка «во время выполнения»), а не просто прекратит его. Лучшее решение почти в каждом случае - использовать флаг. Вот простой, глупый пример того, как его использовать (хотя я уверен, что большинству из вас это не нужно!):

from Tkinter import *

def close_window():
  global running
  running = False
  print "Window closed"

root = Tk()
root.protocol("WM_DELETE_WINDOW", close_window)
cv = Canvas(root, width=200, height=200); cv.pack()

running = True;
# This is an endless loop stopped only by setting 'running' to 'False'
while running: 
  for i in range(200): 
    if not running: break
    cv.create_oval(i,i,i+1,i+1); root.update() 

Это хорошо завершает графическую активность. Вам нужно только проверить running в нужном месте (ах).

0 голосов
/ 29 мая 2011

Используйте closeEvent

def closeEvent(self, event):
# code to be executed
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...