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

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

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

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

Tkinter

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

Q&A

解決済

2回答

3682閲覧

Python3 Tkinter エントリの未入力チェックを実装したいです

person

総合スコア223

Python 3.x

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

Tkinter

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

0グッド

1クリップ

投稿2020/08/04 00:06

Tkinterでエントリを複数個作成します。今回は5個作成します。

ユーザはエントリにデータを入力します。

入力しなければならない個数は決まっていません。
ただし、最低1つは入力します。
入力は上のエントリから順番にします。

そのため、エラー(抜け防止)は

  • データが1つも入力されていないとき
  • 未入力エントリがあり、それより下のエントリに入力があるとき

に発生するようにしたいです。

例えば、下のようにエントリ[]に対し入力した場合

[a]
[]
[]
[d]
[]

2番目と3番目が入力されていないので、この2つはエラーの対象です。
最低1つ入力 かつ 抜けなしならいいので、上の例では5番目はエラーの対象になりません。

そのため、エラーは「2番目と3番目に入力漏れあり」と出るのが理想です。
まあ2番目だけでもいいです。
3番目だけっていうのは違う気がします(ユーザからしたら、一つずつのエラー表示なら「せめて上から指摘しろよ」って感じになりそう)。
テキストボックスの色を変えるとかでもいいです。
とりあえず「○番目」か分かればいいです。

一応判別するためのプログラムを自分で作ってはみたのですが、上からではなく下からチェックしてしまっているからか、上の例だと3番目のエラー表示になってしまいます。

それが下のコードです。
chk()の部分で抜け防止のためのチェックをしています。
一度 5個全てのエントリをget()してから、上から最下入力済みエントリまで比較する方法も考えてはみたのですが、処理が多いような気もしました。(get()してから比較すると2周してるため)

チェック部分の処理効率を重視した場合にほかにどんなチェック方法が考えられますか。

Python

1import tkinter as tk 2 3def chk(): 4 global entries 5 if entries[0].get() == "": 6 print("1番目が未入力") 7 return False 8 for i in range(4): 9 if entries[i].get() == "": 10 if entries[i + 1].get() != "": 11 print("{}番目が未入力".format(i + 1)) 12 return False 13 return True 14 15def pushed(e): 16 if chk() == True: 17 print("o:未入力なし") 18 else: 19 print("x:未入力あり") 20 21win = tk.Tk() 22win.geometry("300x200") 23 24entries = [] 25 26for i in range(5): 27 entry = tk.Entry(win) 28 entry.grid() 29 entries.append(entry) 30 31button = tk.Button(win, text="click", width=10, default="active") 32button.grid() 33 34button.bind("<ButtonRelease>", pushed) 35 36win.mainloop()

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

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

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

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

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

guest

回答2

0

ベストアンサー

1,4 番目に入力がある場合、2,3番目をエラーとして報告する関数

サンプル入力: [1, 0, 0, 1, 0]
サンプル出力: [0, 1, 1, 0, 0]

となるような関数を考えると良いですよ。

イメージ説明

Demo on repl.it

投稿2020/08/04 09:31

teamikl

総合スコア8664

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

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

person

2020/08/05 02:17

この方がソースを書くときに、直感的にわかりやすいですね。
guest

0

疑問点

ただし、最低1つは入力します。

とありましたが、これはどれか一つという事でしょうか?
掲題のコードを見た感じだと1番目(1番上)のエントリーのみ絶対に入力を促している様にも伺えました。

そしてfor文でウィジェットをリストに格納するならば配置していない状態でリストに格納すべきです。
その後に再度for文で一つずつ配置してください。

python

1def chk(): 2 global entries 3 for i, entry in enumerate(entries): 4 result = entry.get() 5 if result == '': 6 print('{}番目が未入力'.format(i+1)) 7 return False 8 return True 9 10entries = [tk.Entry(win) for _ in range(5)] 11[entry.grid() for entry in entries]

またエントリーの色を変える場合には
pushed関数の中身も変えてしまう必要はありますが
chk関数内でreturnはさせずに以下にする事で色を変える事も出来ます。

python

1def chk(): 2 global entries 3 for i, entry in enumerate(entries): 4 result = entry.get() 5 if result == '': 6 print('{}番目が未入力'.format(i+1)) 7 entry['background'] = 'pink' 8 else: 9 entry['background'] = 'white'

その他には、処理にもよりますが
エントリーへの入力が終わった際にボタンを押して次の処理を行うなどといった場合には、
予めボタンにはstate=disabledを設定しておき
Entryに対し「値が入力されていた場合にボタンのstate=enabledを付与する」
といった処理で関連付けることによって、チェックを可能にする方法も。

投稿2020/08/04 02:08

編集2020/08/04 02:13
nto

総合スコア1438

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

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

person

2020/08/05 02:18 編集

◆回答 >> ただし、最低1つは入力します。 > とありましたが、これはどれか一つという事でしょうか? > 掲題のコードを見た感じだと1番目(1番上)のエントリーのみ絶対に入力を促している様にも伺えました。 エントリは上から順に入力するので、結果的に1番上のエントリは絶対に入力します。 ◆質問 > for文でウィジェットをリストに格納するならば配置していない状態でリストに格納すべきです。 > その後に再度for文で一つずつ配置してください。 そうすべき理由は何でしょうか。
nto

2020/08/05 02:35

>> そうすべき理由は何でしょうか。 失礼しました、コメント欄の為内包表記で失礼しますが entries = [tk.Entry(win).grid() for i in range(5)] と .grid()して配置した状態までをリストに格納しているのかと勘違いしておりました。 掲題のコードはリストへの格納と配置は別々で処理が行われていましたね。 entries = [] for i in range(5):   entry = tk.Entry(win).grid()   entries.append(entry) と格納してしまうと後から.get()で入力した内容が取得できなくなってしまうからです。
person

2020/08/05 03:45

これで取得できるのですが、ダメでしょうか? import tkinter as tk def returnPressed(e): global entries print("----------") for i in range(len(entries)): print(entries[i].get()) print("----------") win = tk.Tk() entries = [] for i in range(5): entry = tk.Entry(win) entry.grid() entries.append(entry) win.bind("<Return>", returnPressed) win.mainloop()
nto

2020/08/05 04:09

先に申し上げた通り、entry.grid()で配置した状態でリストに格納しているものと勘違いしており、掲題のコードでは配置していない状態でwidgetのみを格納している様ですので問題ありません。 万が一にentry.grid()を格納していた場合には取得ができなくなる為と記載しております。 お確かめください。
person

2020/08/05 10:39

理解しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問