🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

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

Tkinter

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

Q&A

解決済

1回答

3059閲覧

Python3 Tkinter Toplevelが重なって表示されてしまいます

person

総合スコア224

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2020/05/29 03:56

Tkinterで

  • エントリをクリックしてテンキー表示
  • テンキーで数字を入力
  • テンキーで数字以外が入力されたらエラー表示

を実現したいため下のようにソースコートを書きました。

しかし、エラー表示を閉じた直後にエントリ(テキストボックス)をクリックすると、既にテンキーがあるのにもかかわらずさらにテンキーを表示してしまいます。

Toplevelをテンキーとエラー表示の両方で表示しているのが原因かもしれませんが、エラー表示にはmsgboxではなく、フォントサイズが変更できるToplevelを使いたいです。

以下のコードで、改善する方法があれば教えてください。

実行環境としてはRaspberryPiを考えていますが、可能であればWindows10でも使いたいと思っています。

# main.py import tkinter as tk import tenkey # 実際は親ウィンドウはフルスクリーンで表示 # その上にテンキーを表示(Toplevelは背面に来ないようにする) # テンキーの入力によってはその上からエラー表示 def pushed(ev): global win, e tenkey.tenkey(win, e) win = tk.Tk() e = tk.Entry(win) e.grid() e.bind("<ButtonRelease>", pushed) win.mainloop()
# tenkey.py import tkinter as tk import error def tenkey(win, input_widget): def push_0(input_widget): input_widget.insert(tk.END, "0") def push_1(input_widget): input_widget.insert(tk.END, "1") def push_2(input_widget): input_widget.insert(tk.END, "2") def push_3(input_widget): input_widget.insert(tk.END, "3") def push_4(input_widget): input_widget.insert(tk.END, "4") def push_5(input_widget): input_widget.insert(tk.END, "5") def push_6(input_widget): input_widget.insert(tk.END, "6") def push_7(input_widget): input_widget.insert(tk.END, "7") def push_8(input_widget): input_widget.insert(tk.END, "8") def push_9(input_widget): input_widget.insert(tk.END, "9") def push_AC(input_widget): input_widget.delete(0, tk.END) def push_ok(input_widget): try: tmp = int(input_widget.get()) print(tmp) tenkey_win.grab_release() tenkey_win.destroy() except ValueError: error.error() tenkey_win = tk.Toplevel() tenkey_win.geometry("300x600+500+0") tenkey_win.overrideredirect(True) # 閉じる、最大化、最小化の非表示(Windowsでは機能しない?) tenkey_win.wait_visibility() # grab_set()のエラー回避のため記述 tenkey_win.grab_set() tenkey_win.attributes("-topmost", True) #tenkey_win.transient(win) # 最小化非表示(Raspberry Piでは機能しない?) tenkey_win.rowconfigure((0, 1, 2, 3, 4), weight=1) tenkey_win.columnconfigure((0, 1, 2, 3), weight=1) btn_7 = tk.Button(tenkey_win, text="7", width=5, height=5, command=lambda:push_7(input_widget)) btn_7.grid(row=0, column=0, sticky="nsew") btn_8 = tk.Button(tenkey_win, text="8", width=5, height=5, command=lambda:push_8(input_widget)) btn_8.grid(row=0, column=1, sticky="nsew") btn_9 = tk.Button(tenkey_win, text="9", width=5, height=5, command=lambda:push_9(input_widget)) btn_9.grid(row=0, column=2, sticky="nsew") btn_AC = tk.Button(tenkey_win, text="AC", width=5, height=5, command=lambda:push_AC(input_widget)) btn_AC.grid(row=0, column=3, sticky="nsew") btn_4 = tk.Button(tenkey_win, text="4", width=5, height=5, command=lambda:push_4(input_widget)) btn_4.grid(row=1, column=0, sticky="nsew") btn_5 = tk.Button(tenkey_win, text="5", width=5, height=5, command=lambda:push_5(input_widget)) btn_5.grid(row=1, column=1, sticky="nsew") btn_6 = tk.Button(tenkey_win, text="6", width=5, height=5, command=lambda:push_6(input_widget)) btn_6.grid(row=1, column=2, sticky="nsew") btn_tmp1 = tk.Button(tenkey_win, text="", width=5, height=5, state="disabled") btn_tmp1.grid(row=1, column=3, sticky="nsew") btn_1 = tk.Button(tenkey_win, text="1", width=5, height=5, command=lambda:push_1(input_widget)) btn_1.grid(row=2, column=0, sticky="nsew") btn_2 = tk.Button(tenkey_win, text="2", width=5, height=5, command=lambda:push_2(input_widget)) btn_2.grid(row=2, column=1, sticky="nsew") btn_3 = tk.Button(tenkey_win, text="3", width=5, height=5, command=lambda:push_3(input_widget)) btn_3.grid(row=2, column=2, sticky="nsew") btn_tmp2 = tk.Button(tenkey_win, text="", width=5, height=5, state="disabled") btn_tmp2.grid(row=2, column=3, sticky="nsew") btn_0 = tk.Button(tenkey_win, text="0", width=5, height=5, command=lambda:push_0(input_widget)) btn_0.grid(row=3, column=0, columnspan=4, sticky="nsew") btn_ok = tk.Button(tenkey_win, text="OK", width=5, height=5, command=lambda:push_ok(input_widget)) btn_ok.grid(row=4, column=0, columnspan=4, sticky="nsew")
# error.py import tkinter as tk def error(): # 諸事情により msgbox ではなくフォントサイズを変更できるToplevelを採用 def push_b(): err_win.grab_release() err_win.destroy() err_win = tk.Toplevel() err_win.attributes("-topmost", True) err_win.wait_visibility() err_win.grab_set() l = tk.Label(err_win, text="数字を入力してください", font=("",15)) l.grid() b = tk.Button(err_win, text="close", command=push_b) b.grid()

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

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

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

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

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

guest

回答1

0

ベストアンサー

原因: 毎回新しい Toplevel を作っている為

簡単な回避策:

python

1tenkey_win = tk.Toplevel(name="tenkey")

同じnameを付ける事で、2重になる現象は抑制出来ます。
新しくウィジェット等を生成している点は変わりませんが。


より良い方法は、tenkey_win 生成は初回のみにして
必要に応じて表示/非表示を切り替えます。

親となるFrame 上に各部品を配置して、
表示時はFrame のレイアウト関数呼び出し
非表示は、各レイアウトの_forgetメソッドで出来ます。

投稿2020/05/29 06:13

teamikl

総合スコア8738

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問