web-dev-qa-db-ja.com

Tkinterでウィンドウクローズイベントを処理するにはどうすればよいですか?

Python Tkinterプログラムでウィンドウを閉じるイベント([X]ボタンをクリックする)を処理するにはどうすればよいですか?

100
Matt Gregory

Tkinterは、 protocol handlers と呼ばれるメカニズムをサポートしています。ここで、protocolという用語は、アプリケーションとウィンドウマネージャー間の対話を指します。最も一般的に使用されるプロトコルは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()
137
Matt Gregory

マットは、閉じるボタンの古典的な変更を1つ示しました。
もう1つは、閉じるボタンでウィンドウを最小化することです。
iconify メソッドを使用すると、この動作を再現できます
protocol メソッドの2番目の引数。

以下は、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()

この例では、ユーザーに2つの新しい終了オプションを提供します。
クラシックファイルメニュー->終了、さらに Esc ボタン。

21
Honest Abe

Tkinterアクティビティに応じて、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のみをチェックする必要があります。

4
Apostolos

シンプルバージョンをお試しください:

import tkinter

window = Tk()

closebutton = Button(window, text='X', command=window.destroy)
closebutton.pack()

window.mainloop()

または、さらにコマンドを追加する場合:

import tkinter

window = Tk()


def close():
    window.destroy()
    #More Functions


closebutton = Button(window, text='X', command=close)
closebutton.pack()

window.mainloop()
0
SF12 Study