質問文のコードには複数の問題がありますが、おそらく実際のコードはこれと違っていて、質問に書かれた問題以外は動いているのでしょう。回答者は実際のコードを見ることができないのでわかりませんが。
補足: 削除線の部分は回答中に修正されました。
先頭のtkinetrはtkinterの誤り
placeで各ボタンの位置を(100, 200)に設定しているが、tkinterで生成されるウィンドウのサイズの初期値は200x200なので、ボタンがウィンドウ内に表示されない
ボタンのテキストを設定するオプション引数はtextであって、labelではない
appに対してmainloopを呼び出していないため、メインウィンドウが表示されない。
これらを修正すると、質問文のコードが動くようになり、質問の状況が再現できます。
さて、あなたが作ろうとしている「2つのウィンドウを閉じる」関数に必要なのは、
- メインウィンドウのウィジェットオブジェクト
- サブウィンドウのウィジェットオブジェクト
の2つです。どちらも、tk.Tk()で生成されます。
メインウィンドウのウィジェットオブジェクトを利用するには、変数appにそれが代入された後に関数を書く必要があります。変数appはグローバル変数なので、代入後はどこでもその内容を参照できます。
また、mainloopでイベントループを開始すると、それより後の内容はイベントループの終了後(ウィンドウを閉じた後)にならないと実行されないため、mainloopよりも前に関数を書く必要があります。さもないと、but2のボタンを押したときに、関数が未定義だというエラーが出ます。
サブウィンドウのほうはちょっと複雑です。
サブウィンドウのウィジェットオブジェクトを利用するには、変数app2にそれが代入された後である必要があります。ここで、変数app2は関数new_tk内でのみ有効なローカル変数なので、関数new_tkの処理から抜けると使えなくなります。
すると、変数app2だけが使っていたウィジェットオブジェクトはガベージコレクションにより自動的に削除されてしまいます。
これを避けるには、サブウィンドウもメインウィンドウと同様に関数の外側で生成してグローバル変数に入れる(あなたが自分で作るならこちらがわかりやすいでしょう)か、変数app2以外にもサブウィンドウのウィジェットオブジェクトへの参照を作ります。
以下のコードでは、lambdaという機能を使い、lambdaの引数xに変数app2の値(ウィジェットオブジェクトのID)を代入することで、ガベージコレクションによる自動的な削除を回避しています。
そして、but2のボタンを押すと、その引数xを指定した関数my_closeを呼び出し、そこでサブウィンドウとメインウィンドウをそれぞれdestroyしています。
Python
1import tkinter as tk
2
3
4def new_tk():
5 app2 = tk.Tk()
6 but2 = tk.Button(text='quit', command=lambda x=app2: my_close(x))
7 but2.place(x=100, y=100)
8
9
10app = tk.Tk()
11but = tk.Button(text='new', command=new_tk)
12but.place(x=100, y=100)
13
14
15def my_close(target):
16 target.destroy()
17 app.destroy()
18
19
20app.mainloop()
作っていてどちらを意図しているのかわからないのでそのままにしてありますが、but2をサブウィンドウに表示したいのであれば、以下のように修正してください。
diff
1- but2 = tk.Button(text='quit', command=lambda x=app2: my_close(x))
2+ but2 = tk.Button(app2, text='quit', command=lambda x=app2: my_close(x))
補足: 今回は
pythonのtkで「command」で複数の関数を使いたい
という質問だったので、それに沿った回答になりましたが、「サブウィンドウをメインウィンドウと連動させて閉じたい」というだけなら、サブウィンドウをToplevelで開くのが簡単です。
メインウィンドウが閉じるときにサブウィンドウが連動して閉じるため、but2のcommandには、メインウィンドウを閉じる関数オブジェクトapp.destroyだけを指定すれば事足ります。
Python
1import tkinter as tk
2
3
4def new_tk():
5 tk.Toplevel()
6 but2 = tk.Button(text='quit', command=app.destroy)
7 but2.place(x=100, y=100)
8
9
10app = tk.Tk()
11but = tk.Button(text='new', command=new_tk)
12but.place(x=100, y=100)
13
14app.mainloop()