前提・実現したいこと
Pythonでいいえが押されるまで質問するシステムを作っています。
Tkinterを使い何度も分岐をする機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
エラーメッセージ return self.tk.call('wm', 'geometry', self._w, newGeometry) _tkinter.TclError: can't invoke "wm" command: application has been destroyed
該当のソースコード
import tkinter from tkinter import messagebox # ウインドウ root = tkinter.Tk() root.withdraw() messagebox.showinfo('', '開始!!!!') def ajust_moving(): # データ数入力 root.deiconify() root.title(u"調整") root.geometry("250x120") Static1 = tkinter.Label(text=u'+か-を入れてください!') Static1.pack() EditBox1 = tkinter.Entry() EditBox1.insert(tkinter.END, '+') EditBox1.pack() Static2 = tkinter.Label(text=u'100単位で数字を入れてください') Static2.pack() EditBox2 = tkinter.Entry() EditBox2.insert(tkinter.END, '100') EditBox2.pack() aaa = tkinter.Button(root, text='確定', width='10', command=root.destroy) aaa.pack() value = EditBox1.get() nuaa = EditBox2.get() root.mainloop() anka = 'm:1' + value + 'p' + nuaa + '\r\n' # 文字列の結合 # 相対移動文字列を作る # 関数内関数作ってもいいんじゃね? root.geometry("0x0") # ウィンドウのタイトルバーを消す(Windows用の設定) root.overrideredirect(1) while True: OneMore_adjust = messagebox.askyesno('Adjusts_Onemore', 'もう一度調整しますか?') if OneMore_adjust: ajust_moving() else: break root = tkinter.Tk() root.withdraw() messagebox.showinfo('', '完了!!') #追記のソースコードここから import tkinter from tkinter import messagebox # ウインドウ root = tkinter.Tk() # root.withdraw() def on_start(): messagebox.showinfo('', '開始!!!!') # 次にmainloop内から main_proc() 関数を呼ぶ root.after(0, main_proc) # 0秒後にmain_procという関数を呼ぶという意味 def main_proc(): # ここで設定Windowを Toplevel Widget にて作成 global top top = tkinter.Toplevel(root) top.deiconify() top.title(u"調整") top.geometry("250x120") # 以下に 設定画面を作成(省略) Static1 = tkinter.Label(top, text=u'+か-を入れてください!') Static1.pack() EditBox1 = tkinter.Entry(top) EditBox1.insert(tkinter.END, '+') EditBox1.pack() Static2 = tkinter.Label(top, text=u'100単位で数字を入れてください') Static2.pack() EditBox2 = tkinter.Entry(top) EditBox2.insert(tkinter.END, '100') EditBox2.pack() button = tkinter.Button(top, text='確定', width='10',command=on_closing()) button.pack() sign = EditBox1.get() value = EditBox2.get() root.mainloop() anka = 'm:1' + sign + 'p' + value + '\r\n' # 文字列の結合 # 相対移動文字列を作る # 関数内関数作ってもいいんじゃね? # ser.write(bytes(anka, 'UTF-8')) # ser.write(b'g:\r\n') print(anka) # Toplevel Widgetが閉じられるときは on_close()関数を呼ぶ def on_closing(): top.destroy() # 確認用ダイアログを出す onemore = messagebox.askyesno('Adjusts_Onemore', 'もう一度調整しますか?') if onemore: # 再度 mainloop内から main_proc() 関数を呼ぶ root.after(0, main_proc) else: # 完了ダイアログを出す messagebox.showinfo('', '完了!!') # rootを破棄(これでmainloopを抜けるはず) root.destroy() # 最初にmainloop内から on_start() 関数を呼ぶ root.after(0, on_start) root.mainloop()
試したこと
while文にする前は自分が想像していた動作が実現できました。
あと、Tkinterは何度も実行する仕様ではないということも調べた結果わかりました。
###教えていただきたいこと
最初と最後は、withdraw()で隠したいです。
関数を実行するときは、表示したいとおもっているため 、
deiconify()を使っています。
tkinterでタブを削除した後
While文内のif文を何度も実行してうまく挙動させるに葉どうしたらいいのか?
もしくは、while文を使わないでif文の挙動を何回もできるようにしたいです。
もしくはTkinterを使わないでも実装できるやり方を知りたいです。
#解決コード
サブウィンドウを作成し、それを何度も破壊することでメインウィンドウを削除しないでもよくなった。
※回答欄から転載
Python
1import tkinter 2from tkinter import messagebox 3 4# ウインドウ 5root = tkinter.Tk() 6root.withdraw() 7 8def on_start(): 9 messagebox.showinfo('', '開始!!!!') 10 # 次にmainloop内から main_proc() 関数を呼ぶ 11 root.after(0, main_proc) 12 13def main_proc(): 14 # ここで設定Windowを Toplevel Widget にて作成 15 global top 16 top = tkinter.Toplevel(root) 17 top.deiconify() 18 top.title(u"調整") 19 top.geometry("250x120") 20 # 以下に 設定画面を作成(省略) 21 22 # Toplevel Widgetが閉じられるときは on_close()関数を呼ぶ 23 top.protocol("WM_DELETE_WINDOW", on_closing) 24 25def on_closing(): 26 # Toplevel Widgetを破棄 27 top.destroy() 28 # 確認用ダイアログを出す 29 onemore = messagebox.askyesno('Adjusts_Onemore', 'もう一度調整しますか?') 30 if onemore: 31 # 再度 mainloop内から main_proc() 関数を呼ぶ 32 root.after(0, main_proc) 33 else: 34 # 完了ダイアログを出す 35 messagebox.showinfo('', '完了!!') 36 # rootを破棄(これでmainloopを抜けるはず) 37 root.destroy() 38 39# 最初にmainloop内から on_start() 関数を呼ぶ 40root.after(0, on_start) 41root.mainloop() 42
##注意点
commandで関数を指定するときは、
command=on_closing()
ではなく、
command=on_closing
と記述する。
commandパラメータに渡すのは、「関数」を渡す。
括弧つきで記述すると、その場で関数が実行され、その戻り値がcommandパラメータに渡すという意味になってしまうので、注意が必要。
回答1件
あなたの回答
tips
プレビュー