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

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

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

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

Python

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

Q&A

解決済

2回答

1077閲覧

tkinter をエラーなく、×ボタンで閉じたいです。

tomomonX

総合スコア28

Tkinter

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

Python

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

0グッド

0クリップ

投稿2022/09/12 17:56

前提

tkinter をエラーなく、×ボタンで閉じたいです。

実現したいこと

mainloopを使わず、whileとupdateでtkinterのウィンドウを立ち上げて、×ボタンで終了したいです。
whileとupdateで代用する理由はウィンドウの内容を条件によって更新したいからです。
該当のソースコードではシンプルに白から白に更新しています。(本来はいろんな条件分岐します。)

発生している問題・エラーメッセージ

File "D:(割愛)\benkyo.py", line 38, in <module> btn[i]['bg']='white' File "C:\Users\namae\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1657, in __setitem__ self.configure({key: value}) File "C:\Users\namae\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1646, in configure return self._configure('configure', cnf, kw) File "C:\Users\namae\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1636, in _configure self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) _tkinter.TclError: invalid command name ".!canvas.!button"

該当のソースコード

実際は500行以上にわたるコードなので、シンプルにして必要なところだけ記載します。

python

1import tkinter as tk 2 3root = tk.Tk() 4label = tk.Label(root, text="-") 5label.pack() 6root.geometry('1920x1080') 7canvas = tk.Canvas( 8 root, 9 width = 1920, # 水平サイズ 10 height = 500, # 垂直サイズ 11) 12canvas.pack() # 配置 13 14 15for i in range(18): 16 btn={ 17 i:[], 18 } 19 20for i in range(6): 21 btn[i]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 22 btn[i+6]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 23 btn[i+12]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 24 btn[i+18]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 25 btn[i].grid(row=0,column=i) 26 btn[i+6].grid(row=1,column=i) 27 btn[i+12].grid(row=2,column=i) 28 btn[i+18].grid(row=3,column=i) 29 30def close_window(): 31 root.destroy() 32 33button = tk.Button(text = "Click and Quit", command = close_window) 34button.pack() 35 36while True: 37 for i in range(24): 38 btn[i]['bg']='white' 39 label.update() 40

試したこと

下記コードを追記して閉じてみましたがやはりエラーになります。

def close_window(): root.destroy() button = tk.Button(text = "Click and Quit", command = close_window) button.pack()

原因と対策わかる方いましたら教えてください。
invalid command nameでググっても有効な対策を見つけられませんでした。

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

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

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

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

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

guest

回答2

0

求めてる回答ではないのですが・・・

whileとupdateで代用する理由はウィンドウの内容を条件によって更新したいからです。

afterを使ってイベントドリブンな処理にすることを検討してみてはいかがでしょうか?
mainloopを使ってもウィンドウの内容を条件によって更新することはできますので。

それと、

python

1for i in range(18): 2 btn={ 3 i:[], 4 }

このループ処理は以下のようになって意味がなくて、

python

1>>> for i in range(18): 2... btn={ 3... i:[], 4... } 5... 6>>> btn 7{17: []}

以下で十分ですよ。

python

1btn = {}

afterを使ったサンプルコード:

py

1import tkinter as tk 2 3root = tk.Tk() 4label = tk.Label(root, text="-") 5label.pack() 6root.geometry('1920x1080') 7canvas = tk.Canvas( 8 root, 9 width = 1920, # 水平サイズ 10 height = 500, # 垂直サイズ 11) 12canvas.pack() # 配置 13 14 15btn={} 16 17for i in range(6): 18 btn[i]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 19 btn[i+6]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 20 btn[i+12]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 21 btn[i+18]=tk.Button(canvas, text="", width=25,font=("MSゴシック", "16")) 22 btn[i].grid(row=0,column=i) 23 btn[i+6].grid(row=1,column=i) 24 btn[i+12].grid(row=2,column=i) 25 btn[i+18].grid(row=3,column=i) 26 27def close_window(): 28 root.destroy() 29 30button = tk.Button(text = "Click and Quit", command = close_window) 31button.pack() 32 33def update(): 34 for i in range(24): 35 btn[i]['bg']='white' 36 root.after(100, update) 37 38root.after(100, update) 39root.mainloop()

投稿2022/09/12 23:18

編集2022/09/13 03:12
shiracamus

総合スコア5406

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

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

tomomonX

2022/09/13 16:45

ありがとうございます。そういうやり方もあるんですね。 btnのご指摘もありがとうございます。
guest

0

ベストアンサー

close_window() はフラグをセットをするだけにして、メインループがフラグを見て終了するようにしてみては?

running = True def close_window(): global running running = False button = tk.Button(text = "Click and Quit", command = close_window) button.pack() root.protocol("WM_DELETE_WINDOW", close_window) while running: for i in range(24): btn[i]['bg']='white' label.update()

投稿2022/09/12 22:13

sigsegv

総合スコア895

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

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

tomomonX

2022/09/13 16:45

ありがとうございます。うまく動作しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問