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

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

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

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

Tkinter

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

Q&A

解決済

3回答

1035閲覧

Python3 Tkinter エントリにQRコードを入力したら各ラベルにそのデータを表示したい

person

総合スコア223

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2022/06/13 04:23

EntryにQRコードを入れたら、各Labelにデータを表示したいです。
QRコードのエントリは入力してすぐにクリアします。

次のようにコードを作成したのですが、気になることがあります。

afterで繰り返しているので、文字を入れてからQRのデータ表示やエントリのクリアをするまでの時間にばらつきがあります。

文字を入れてから一定時間後に表示やクリアなど目に見える処理したほうが気にならないのですが、そのような方法はありますか?

Python

1import tkinter as tk 2from tkinter import ttk 3 4def loop(): 5 # 取得 6 qr = qr_entry.get() 7 8 # 表示 9 if qr.count(",") == 1: 10 values = qr.split(",") 11 id_label["text"] = values[0] 12 name_label["text"] = values[1] 13 14 # クリア 15 qr_entry.delete(0, "end") 16 17 # 再び呼び出し 18 qr_entry.after_idle(qr_entry.after, 500, loop) 19 20root = tk.Tk() 21 22qr_entry = ttk.Entry(root) 23qr_entry.grid() 24 25id_label = ttk.Label(root) 26id_label.grid() 27 28name_label = ttk.Label(root) 29name_label.grid() 30 31qr_entry.after_idle(loop) 32 33root.mainloop()

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

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

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

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

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

guest

回答3

0

自己解決

2023/03/07 変更

下記で実現できました。
QRコードにカンマが含まれていれば、カンマ区切りの1番目と2番目をラベルに表示。そうでなければラベルに空白のみ表示。
エントリのクリアはtk.StringVar().set(""), tk.Entry().delete()のどちらでも問題ありませんでした。

Python

1import tkinter as tk 2from tkinter import ttk 3 4def func(): 5 qr = qr_sv.get() 6 7 if qr.count(",") >= 1: 8 values = qr.split(",") 9 id_label["text"] = values[0] 10 name_label["text"] = values[1] 11 else: 12 id_label["text"] = "" 13 name_label["text"] = "" 14 15 qr_sv.set("") 16 17 18def qr_changed(*args): 19 global after_id 20 # 入力中は呼ばずに、入力が完了したらfunc呼び出し 21 if after_id: 22 qr_entry.after_cancel(after_id) 23 if qr_sv.get(): 24 after_id = qr_entry.after(1000, func) # 入力後約1000ミリ秒経過したら入力完了とみなす 25 26root = tk.Tk() 27 28after_id = None 29 30qr_sv = tk.StringVar() 31qr_sv.trace("w", qr_changed) 32qr_entry = ttk.Entry(root, textvariable=qr_sv) 33qr_entry.grid() 34 35id_label = ttk.Label(root) 36id_label.grid() 37 38name_label = ttk.Label(root) 39name_label.grid() 40 41root.mainloop()

投稿2022/06/15 01:24

編集2023/03/07 04:48
person

総合スコア223

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

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

person

2023/03/07 04:50 編集

回答を変更したので、後から見つかった問題は削除します。
guest

0

QRコードを入れた時というのが解りませんが、
Entry ウィジェットのデータが変更されたときであれば、StringVar を使い、
trace メソッドを使うことで 値が変化された時に関数を呼び出すことが可能です。

python

1 2import tkinter as tk 3from tkinter import ttk 4 5root = tk.Tk() 6qr_str = tk.StringVar() # ※ 関数内で作る場合、変数の生存期間には注意 7 8def on_qr_changed(*_): 9 text = qr_entry.get() 10 ... 11 qr_str.set("") 12 13qr_str.trace("w", on_qr_changed) 14 15qr_entry = ttk.Entry(root, textvar=qr_str) 16qr_entry.grid() 17 18id_label = ttk.Label(root) 19id_label.grid() 20 21name_label = ttk.Label(root) 22name_label.grid() 23 24root.mainloop()

qr_entry.after_idle(qr_entry.after, 500, loop)

after の間隔が小さすぎて GUI が応答なしになるのを防ぐ時に、
after_idle で after を呼び出すことはありますが、
この場合であれば qr_entry.after(500, loop) で良いはずです。

参考: https://wiki.tcl-lang.org/page/after+idle

投稿2022/06/13 05:24

teamikl

総合スコア8664

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

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

0

StringVarをEntryに紐づけるとStringVarのtraceメソッドにて更新時に関数を呼び出すことができます。
参考:変数の変化に応じたアクション

なお、提示、回答コードともに、つねにqrのエントリをクリアしていますが
ラベルにセットしたときだけクリアするほうが自然な動きになるような気がします。

python

1iimport tkinter as tk 2from tkinter import ttk 3 4def qr_changed(*args): 5 qr = qr_sv.get() 6 7 # 受信完了 8 if qr and qr[-1] == '\n': 9 qr = qr.rstrip() 10 11 # 正しいデータ 12 if qr.count(",") == 1: 13 values = qr.split(",") 14 id_label["text"] = values[0] 15 name_label["text"] = values[1] 16 17 # クリア 18 qr_entry.delete(0, "end") 19 20root = tk.Tk() 21 22qr_sv = tk.StringVar() 23qr_sv.trace("w", qr_changed) 24qr_entry = ttk.Entry(root, textvariable=qr_sv) 25qr_entry.grid() 26 27id_label = ttk.Label(root) 28id_label.grid() 29 30name_label = ttk.Label(root) 31name_label.grid() 32 33root.mainloop()

投稿2022/06/13 05:24

編集2022/06/13 07:41
can110

総合スコア38266

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

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

person

2022/06/13 06:20 編集

回答ありがとうございます。 > traceメソッドにて更新時に関数を呼び出すことができます。 今手元にQRコードリーダーがないので動作確認出来ないのですが、 以前QRコードを試しに読んだとき キーボードを高速で入力したようにエントリに値が入ったと思うのですが、 入力途中で解釈したりなどの問題はないでしょうか? (単に表示処理が追い付いていないだけ?) > ラベルにセットしたときだけクリアするほうが自然な動きになるような気がします この部分は、入力したテキストが想定通りではなかったときに 処理しない(もしくはエラー表示) + クリアする にしないとテキストが残ったままになってしまうと思ったのでこうしました。 クリア用のボタン等を設けると押す手間が出てしまうため。 どうせ消すなら自動のほうがいいと思いました。 → 上にある途中解釈等の問題を防ぐために自動クリアを無しにしましたか?
can110

2022/06/13 06:21

> キーボードを高速で入力したように値が入ったと思うのですが、 > ラベルにセットしたときだけクリアするほうが自然な動きになるような気がします そのあたりはQRコードリーダーの挙動によるかと思うので何とも言えません。 こちらでは「123,456」のような文字列をコピー&ペーストで一括入力することで動作を確認しています。 入力が1文字ずつだったとしても、改行コードのような終端の分かる文字が最後に入ってくるなら回答コードを少し修正するだけで処理はできるはずです。
person

2022/06/13 07:20

動作確認できるようになり次第確認してみます
can110

2022/06/13 07:41

一般的なQRコードリーダーは読取完了すると最後に改行コードを出力するようなので、それに対応したコードに修正しました。 1文字ずつでも一括でも動作します。
person

2022/06/15 00:23 編集

QRコードリーダーを使ってやってみましたがダメでした。 ・懸念していたように、aaa,bbbをコピペしたように、一気にエントリに文字列が入ることなく、徐々に入っていくためtrace()で期待通りの動作にならない ・QRコードに改行コードを付加したが、stringvarでgetした文字列に改行が入っていないからかラベルに文字列が表示されない (QRコードの設定上、最後にEnterする設定にはしてある。テキストエディタなどでQRコード読み取りすればきちんと改行される。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問