質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2641閲覧

tkinterのボタンに二つの命令(一つはtkinterのウインドウ自体を終了させる)を割り当てたい。

Aki1000

総合スコア78

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/11/07 02:24

tkinterを使って、メインのプログラム実行中に非常停止ボタンを表示しているプログラムを作っています。
停止ボタンを押すと、問題なくメインのプログラムは閉じるのですが、その後もう一回そのウインドウを閉じるためにクリックしなければなりません。停止ボタンを押したら、その停止ボタンを表示しているtkinterのウインドウ自体閉じるようにしたいです。

以下のコードです。よろしくお願いします。

Python

1from multiprocessing import Process 2from time import sleep 3import tkinter 4import sys 5import os, signal 6 7def make_cmd(): 8 return lambda: os.kill(os.getppid(), signal.SIGTERM) 9 10def StopBottun(): 11 root = tkinter.Tk() 12 root.attributes("-topmost", True) 13 label = tkinter.Label(root, text='StopBottun') 14 label.pack() 15 button1 = tkinter.Button(root, text='Exit', command=make_cmd()) 16 button1.pack() 17 root.mainloop() 18 19def main(): 20 i1 = Process (target=StopBottun) 21 i1.start() 22 while True: 23 sleep(2) 24 print("test") 25 #ここから先でメインプログラムが流れる 26 27if __name__ == "__main__": 28 main()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

make_cmd() 関数に引数 root を追加し

Python

1def make_cmd(root): 2 # mainプロセスの終了 3 os.kill(os.getppid(), signal.SIGTERM) 4 # Tkを終了 5 root.destroy()

のようにして、Buttonのcommandにて

Python

1 button1 = tkinter.Button(root, text='Exit', command=lambda : make_cmd(root))

のようにパラメータを渡すようにすると良いのではないでしょうか。

投稿2018/11/07 02:54

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2018/11/07 03:01

×ボタンからウインドウを閉じてもメインプロセス終了しないのが気になります。 元のプログラムがそういう仕様なら仕方がないのですが。
magichan

2018/11/07 03:10

確かにそのとおりですね。 とりあえず、"X" 押したときも同様の処理をいれて root.protocol("WM_DELETE_WINDOW", lambda : make_cmd(root)) をでもしておいたほうが良いかもしれません
can110

2018/11/07 03:16

なるほど。WM_DELETE_WINDOWというイベントがあるのですね。勉強になりました。返信ありがとうございます。
Aki1000

2018/11/07 04:57 編集

ありがとうございます!!!!!! 動きました!! すいません、問題無く動くのですが後学のために、よろしければ、もう少し、2点について解説いただけるとありがたいです。 1 lambdaが無名関数で、ネットでサンプルがあるのがlambaの「:」の前に変数を「:」の後ろに式を入れると、関数を設定したが如く一行で定義が出来る。何でかよく理解してないけどしばしばtkinterのボタンが押されたときにcommandが動作するようにするときに使っているサンプルがある……これは何なんでしょう。どういう働きをするんでしょう? 2 もっと基本的な事ですいませんが、 defで設定した関数に引数を渡すのに文字列や数値しか考えていなかったのですが、make_cmd(root)はtkinterのメソッド(? インスタンス?)を引数として渡すという理解でいいんでしょうか?
magichan

2018/11/07 05:26

順番が逆になりますが、まずは 2 から。 これは、その理解で間違いありません。渡しているのは "root = tkinter.Tk()" で生成したインスタンスとなります。
magichan

2018/11/07 05:39

次ぎに 1 ですが、まず基本事項として、 Button()などのcommandパラメータに設定するのは『関数』となります。仮に "def hoge()" のような関数がある場合は "command=hoge" のように記述することで Buttonが押されたときに hoge関数 が呼ばれることになります。 ここで、よくある間違いとしては "command=hoge()" のような書き方で、これでは『hoge関数を実行して、その戻り値を command に設定する』という意味になってしまいますので意図した動作になりません。 で、この設定する関数ですが、無名関数 lambda で置き換えることも出来ます。 この場合 Buttonを押したときに : より右側の処理が実行さることとなります。
magichan

2018/11/07 05:44

今回の回等の場合、Button を押した時に単に make_cmd関数が動作するとよいならば "command=make_cmd" と記述できたのですが、引数として root を渡す必用がありますので、commandにはlambda関数を渡して : の右側の処理(Buttonを押したときの処理)で make_cmd(root) として引数つきでmake_cmd関数を実効しているということになります。
Aki1000

2018/11/07 06:43

なるほど。command=hoge()だとcommandに結果を代入するという事になる。なのでcommand=hoge(root)ではエラーが出る。lambaを使うと:以降を実行という関数なので、その関数としてhoge(root)を指定するとそれが実行される、という感じですね。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問