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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Tkinter

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

Python

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

Q&A

解決済

2回答

1140閲覧

tkinterの違いボダン関数からプッシュアウトグラフを一斉消したい

Deng

総合スコア16

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Tkinter

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

Python

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

0グッド

0クリップ

投稿2021/09/15 01:43

rootに2Dボタン、3DボタンとENDブタンがあります。2Dと3Dをクリックすると、それぞれ対応したデータを処理して、plt.plotの2D、3Dグラフが表示させます。そして、ENDボタンで、終了したいですが、rootを終了できましたが、プッシュアウトした(plt.show())グラムが残りました。

どうすれば、ENDボタンで、グラムを含めて、一斉に終了できますか?教えてください。よろしくお願いします。

import tkinter,os import matplotlib.pyplot as plt from tkinter import * from tkinter import ttk #終了ブタン def button_end(): root.quit() root.destroy() #2Dグラフ def button_2d(): global raw_data,second,data_name if second ==None or not second.winfo_exists(): second = tkinter.Toplevel() second.title("2d") second.geometry() x=[1,2,3,4,5] y=[2,3,1,4,8] plt.plot(x,y) second.destroy() plt.show() #3Dグラフ def button_3d(): global raw_data,third,data_name if third ==None or not third.winfo_exists(): third = tkinter.Toplevel() third.title("3d") third.geometry() fig = plt.figure(figsize=(6,6)) ax = fig.add_subplot(111, projection='3d') x=[1,2,3,4,5] y=[8,4,1,2,1] z=[2,4,6,8,10] ax.plot(x, y, z) third.destroy() plt.show() if __name__ == " __main__": def main(): pass root = tkinter.Tk() root.title("test") root.geometry("+0+0") second = None third = None frame_top = Frame(root, bd=4, relief=GROOVE) # widgetの設定 btn_end = ttk.Button(frame_top,text='END',command = button_end) btn_2d = ttk.Button(frame_top,text='2D', command = button_2d) btn_3d = ttk.Button(frame_top,text='3D', command = button_3d) # widgetの配置 frame_top.grid (row = 0, column = 0, sticky = W) #in root btn_2d.grid(row=0,column=1,sticky = W) #in frame_top btn_3d.grid(row=0,column=2,sticky = N) #in frame_top btn_end.grid(row=0,column=3,sticky = N) #in frame_top root.mainloop()

環境:Win10、Python3.8

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

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

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

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

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

guest

回答2

0

自己解決

subwindowをやめました。Figも一つにまとめました。

何かございましたら、ご指摘をいただくようにお願いします。

Python

1import tkinter,os 2import matplotlib.pyplot as plt 3from tkinter import * 4from tkinter import ttk 5 6def button_end(): 7 root.quit() 8 root.destroy() 9 plt.close() 10 11def button_2d(): 12 plt.clf() 13 x=[1,2,3,4,5] 14 y=[2,3,1,4,8] 15 a = plt.plot(x,y) 16 17 #plt.show(block=False) (しなくでも、いいです。) 18  plt.show() 19 20def button_3d(): 21 22 plt.clf() 23 24 ax = fig.add_subplot(111, projection='3d') 25 26 x=[1,2,3,4,5] 27 y=[8,4,1,2,1] 28 z=[2,4,6,8,10] 29 30 ax.plot(x,y, z) 31 #plt.show(block=False) (しなくでも、いいです。) 32 plt.show() 33 34if __name__ == " __main__": 35 36 def main(): 37 pass 38 39root = tkinter.Tk() 40root.title("test") 41root.geometry("+0+0") 42 43frame_top = Frame(root, bd=4, relief=GROOVE) 44 45# widgetの設定 46btn_end = ttk.Button(frame_top,text='END',command = button_end) 47btn_2d = ttk.Button(frame_top,text='2D', command = button_2d) 48btn_3d = ttk.Button(frame_top,text='3D', command = button_3d) 49 50# widgetの配置 51frame_top.grid (row = 0, column = 0, sticky = W) #in root 52 53btn_2d.grid(row=0,column=1,sticky = W) #in frame_top 54btn_3d.grid(row=0,column=2,sticky = N) #in frame_top 55btn_end.grid(row=0,column=3,sticky = N) #in frame_top 56 57 58fig = plt.figure(figsize=(6,6)) 59 60root.mainloop() 61

投稿2021/09/16 09:01

編集2021/09/16 09:17
Deng

総合スコア16

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

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

teamikl

2021/09/16 23:58

> plt.show(block=False) (しなくでも、いいです。) 見た目の挙動的には問題ないかもしれませんが、 内部の動作的には2点程問題があります。 [1] mainloop と plt.show の併用は、イベントループの競合 [2] バックエンドが異なる場合、tkinter はフリーズする 例えば、button_2d を呼び出した後に、button_3d を呼び出した場合の関数の呼び出しが mainloop  button_2d   plt.show    button_3d # 問題点: 関数 button_2d 内の plt.show 内で呼び出される     plt.show plt.show() 呼び出しはブロッキング処理になり、 その後のコードは内部のループを抜けるまで実行されません。 tkinter の GUI のイベントは mainloop で処理されてるのですが、 button_2d を呼び出した後に mainloop に戻らないと tkinter がフリーズする可能性があります。 問題ない場合は、plt.show のバックエンドが tkinter で、 plt.show 内部で tkinter のイベントが処理されている場合に限ります。 # block=False にすることで mainloop に処理が戻り、 # button_3d は mainloop から呼び出される mainloop  button_2d   plt.show(block=False)  button_3d   plt.show(block=False) バックエンド次第では plt.show(block=False) を定期的に呼び出す必要があったり plt.show 呼び出し自体不要な場合もあります。もし、他の環境で動かす予定がある場合は、 環境の違いにより挙動が異なる可能性がある点に注意してください。
Deng

2021/09/17 02:16

ご教授ありがとうございました。よく勉強になりました。
guest

0

plot.showにオプション引数block=Falseを指定しておけば、plt.showのウィンドウが表示されている間もrootウィンドウを操作でき、ENDボタンを押すとrootウィンドウとplt.showのウィンドウが共に閉じるはずです。

block=Falseを指定しない、あるいはblock=Trueを指定すると、plt.showのウィンドウを閉じるまでrootウィンドウは操作に反応しなくなります。

もっとも、その間もイベントは貯えられているので、ENDボタンを押し(この時点では何も起きない)→plt.showのウィンドウを閉じる→(このタイミングでENDボタンが押されて)rootウィンドウが閉じる、という動作になります。


IDLEから実行した場合は、rootウィンドウを閉じても、それまでに開いたplt.showのウィンドウは閉じません。これは、IDLEのウィンドウ("IDLE Shell X.X.X"と書いてあるほう)でPythonのプロセスが実行中のままになっていて、その子プロセスであるplt.showのウィンドウも閉じないのだと思われます。

実際に、IDLEのウィンドウ("IDLE Shell X.X.X"と書いてあるほう)を閉じると、plt.showのウィンドウも一緒に閉じますし、「Run」→「Run... Customized」(Shift-F5キー)でコードを実行する際に「Restart Shell」にチェックを付けても、古いplt.showのウィンドウは閉じます。

ということで、IDLEでは「ENDボタンを押すとplt.showのウィンドウも閉じる」という動作を実現するのは無理ですね。Visual Studio Codeへの移行を考えられてはどうでしょうか。

投稿2021/09/15 13:34

編集2021/09/16 05:56
Daregada

総合スコア11990

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

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

Deng

2021/09/15 23:05

Daregada様 教えていただきまして、ありがとうございました。しかし、 plt.show(block=False)を追加しましたが、依然に変わりません。plt.show()が閉じませんでした。Matplotlibは Ver.3.4.2を使っています。
Daregada

2021/09/15 23:48

OSはWindows 10、Python 3.8は判明していますが、その他の情報を教えてください。 たとえば、コードを書いているアプリ(VSCodeなど)、Jupyterを使っているか否か、などです。
Deng

2021/09/16 04:52

返事が遅れまして、申し訳ございません。PythonのIDLE3.8(64bit)を使っています。
Daregada

2021/09/16 05:49

確かに、IDLEから実行すると、rootウィンドウを閉じてもグラフのウィンドウが閉じませんね。
Deng

2021/09/16 06:26

何か根本的な課題があると思います。しっかり勉強させていただきます。
teamikl

2021/09/16 08:49

横からコメント失礼します。 matplot.pyplot のバックエンドについて調べて見て下さい。 tkinter 以外のバックエンドが選ばれている場合、 別のGUIライブラリでグラフが表示されてるので、 tkinter のウィンドウを閉じても、想定されてるような挙動にならない可能性があります。 解消方法としては2通り - バックエンドに tkinter が使われるものを選ぶ。→ 回答で想定されてるような挙動になるはずです。 - plt.show を使わずに、tkinter に埋め込む方法で実装する。 (検索用ヒント: FigureCanvasTkAgg)
Deng

2021/09/16 08:56

teamikl様 ありがとうございました。後ほど、やってみます。ちなみに、私が解決方法を見つけました。Daregada様のヒントを参考しました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問