Toplevelでwindowを生成した際にgrab_set()でモーダルにしてしまう方法もありますが、モーダルにはしたくない場合にどうしたらいいのか困ったのでいろいろ調べて以下のようなコードにたどり着きました。
- Toplevelのインスタンスを保有するクラス(Subwindow)を用意する。保有するのであって継承はしない。
- Toplevelで生成したwindowが閉じられた時に発生する
WM_DELETE_WINDOW
イベントをハンドリングして、ToplevelのインスタンスをNoneにする。 - Subwindowを開く時にToplevelのインスタンスがNoneかどうかチェックし、NoneであればToplevelのインスタンスを生成する。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
try:
import tkinter as tk
except:
import Tkinter as tk
class Subwindow(object):
def __init__(self, parent):
self.parent = parent
self.win = None
def open(self):
if not self.win:
self.win = tk.Toplevel(self.parent)
self.win.protocol('WM_DELETE_WINDOW', self.close)
self.win.focus()
def close(self):
self.win.destroy()
self.win = None
if __name__ == '__main__':
root = tk.Tk()
subwin = Subwindow(root)
menu = tk.Menu(root)
menu.add_command(label='Sub', command=subwin.open)
root.config(menu=menu)
root.mainloop()