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

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

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

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

Tkinter

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

Q&A

解決済

1回答

1492閲覧

Tkinterを使用した各Entryでエンターが押された時のCallback関数内でリストの内容を取得方法を教えてください(前回の続き)

tatsu0117

総合スコア11

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2020/03/03 02:30

###Callback関数内でリストの内容を取得したいです
昨日質問させていただいた内容の続きになります。
↓前回の質問はこちらです。
Tkinterを使用してアクティブなEntryの取得方法を教えてください
前回ご回答いただいた方法でやりたいこと(行の追加、カーソル位置の移動)ができました。
ですが、現況のプログラムではすでに入力がされている行であっても、
新しく行が追加されるため書いてある内容がクリアされてしまいます。
そこで、
1案:Callback関数内ですでに入力されている値の有無を取得して、値がある場合はその内容を反映
2案:すでにその行が追加されている場合は処理を行わない
といった方法を取りたいと思っております。
###該当のソースコード

Python

1import tkinter as tk 2from tkinter import ttk 3from tkinter import filedialog 4import pandas as pd 5from tkinter import * 6 7#入力用のGUI 8def GUI_Input(n): 9 list_Items1 = [0] * n 10 def addText(event): 11 # イベントが発行された(<Return>が押された)Widgetを表示 12 #print(event.widget) 13 # イベントが発行された(<Return>が押された)Widgetのグリッド位置 14 #print(event.widget.grid_info()['row']) 15 activerow = event.widget.grid_info()['row'] 16 #項目1追加 17 label0 = ttk.Label(frame0,text=activerow+1) 18 label0.grid(row=activerow+1, column=0) 19 #print(label0) 20 i = activerow+1 21 list_Items1 = [0] * (activerow+1) 22 i = activerow+1 23 list_Items1[i-1] = tk.StringVar() 24 entry_Item1 = ttk.Entry(frame0, 25 textvariable=list_Items1[i-1], 26 width=10) 27 entry_Item1.grid(row=i,column=1) 28 entry_Item1.bind("<Return>", addText) #全てのEntryにbind 29 entry_Item1.focus_set() 30 root = tk.Tk() 31 root.title('Table Input') 32 33 #入力用フレーム 34 frame0 = ttk.Frame(root) 35 frame0.grid(row=0, column=0) 36 37 #項目をつくる 38 list_Labels = ['a', 'b', 'c','d','e','f','g','h','i','j'] 39 for i in range(0, len(list_Labels)): 40 label0 = ttk.Label(frame0, 41 text=list_Labels[i]) 42 label0.grid(row=0, column=i) 43 44 45 #項目1 46 for i in range(0, n): 47 label0 = ttk.Label(frame0, 48 text=i+1) 49 label0.grid(row=i+1, column=0) 50 #項目2 51 for i in range(0, n): 52 list_Items1[i] = tk.StringVar() 53 entry_Item1 = ttk.Entry(frame0, 54 textvariable=list_Items1[i], 55 width=10) 56 entry_Item1.focus_set() 57 entry_Item1.grid(row=i+1,column=1) 58 entry_Item1.bind("<Return>", addText) #全てのEntryにbind 59 #項目3 60 list_Items2 = [0] * n 61 for i in range(0, n): 62 list_Items2[i] = ttk.Combobox(frame0, 63 state='readonly', 64 width=10) 65 list_Items2[i]['values'] = ('a', 'b', 'c', 'd', 'e', 'f') 66 list_Items2[i].grid(row=i+1, column=2) 67 #項目4 68 list_Items3 = [0] * n 69 for i in range(0, n): 70 list_Items3[i] = tk.StringVar() 71 entry_Item3 = ttk.Entry(frame0, 72 textvariable=list_Items3[i], 73 width=10) 74 entry_Item3.grid(row=i+1,column=3) 75 #項目5 76 for i in range(0, n): 77 label1 = ttk.Label(frame0, 78 text=i+1,width=10,anchor='c') 79 label1.grid(row=i+1, column=4) 80 #項目6 81 for i in range(0, n): 82 label2 = ttk.Label(frame0, 83 text=i+1,width=10,anchor='c') 84 label2.grid(row=i+1, column=5) 85 #項目7 86 for i in range(0, n): 87 label3 = ttk.Label(frame0, 88 text=i+1,width=10,anchor='c') 89 label3.grid(row=i+1, column=6) 90 #項目8 91 for i in range(0, n): 92 label4 = ttk.Label(frame0, 93 text=i+1,width=10,anchor='c') 94 label4.grid(row=i+1, column=7) 95 #項目9 96 for i in range(0, n): 97 label5 = ttk.Label(frame0, 98 text=i+1,width=10,anchor='c') 99 label5.grid(row=i+1, column=8) 100 #項目10 101 for i in range(0, n): 102 label6 = ttk.Label(frame0, 103 text=i+1,width=10,anchor='c') 104 label6.grid(row=i+1, column=9) 105 l1 = ttk.Label(frame0,text=1) 106 root.mainloop() 107 108#nの数を変えて、表の行数を変える 109n = 2 110GUI_Input(n)

###試したこと
21行目のlist_Items1 = [0] * (activerow+1)を
list_Items1 = list_Items1.append(0)
のようにすれば行けると思ったのですが、
UnboundLocalError: local variable 'list_Items1' referenced before assignment
といったエラーメッセージがでてうまくいきませんでした。
なにか良い方法はないかご教示いただけますと幸いです。
お力添えよろしくお願いいたします。

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

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

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

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

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

t_obara

2020/03/03 06:50

お聞きになりたい本当に困っている点に絞り、必要最小限のコードにしてお聞きになると、回答が得られやすくなると思います。 エラーメッセージに対応するだけであれば、tkinterは全く関係なく、言語仕様の話ですが、より適切な回答を得たいのであれば、なおさら必要な要素だけに絞ることをお勧めします。
tatsu0117

2020/03/03 13:25

ご指摘いただきありがとうございます。 どのようにお伝えするのがベストなのかまだまだ分かっておらずご理解いただきにくい質問となってしまい大変申し訳ございません。 今後、より必要な内容に絞れるようにしたいと思います。
guest

回答1

0

ベストアンサー

ジャストアイデアです。

単純に、どの行のEntryで Returnが押されたかを判定し、最終行の場合のみ行の追加処理を行い、それ以外の時は単純にフォーカスの移動だけを行うとよいのではないでしょうか。

Python

1 def addText(event): 2 row_size = len(list_Items1) 3 activerow = event.widget.grid_info()['row'] 4 5 if row_size == activerow: 6 #項目1追加 7 label0 = ttk.Label(frame0,text=activerow+1) 8 label0.grid(row=activerow+1, column=0) 9 list_Items1.append(tk.StringVar()) 10 entry_Item1 = ttk.Entry(frame0, 11 textvariable=list_Items1[activerow], 12 width=10) 13 entry_Item1.grid(row=activerow+1,column=1) 14 entry_Item1.bind("<Return>", addText) #全てのEntryにbind 15 entry_Item1.focus_set() 16 else: 17 # row : activerow+1 , column : 1 のWidgetを検索 18 for w in frame0.winfo_children(): 19 if (w.grid_info().get('row') == activerow+1) and (w.grid_info().get('column') == 1): 20 w.focus_set() 21 break

投稿2020/03/03 07:40

magichan

総合スコア15898

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

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

tatsu0117

2020/03/03 13:23

ご回答いただきありがとうございます! ご教示いただいた方法で動作できました。 やりたかった内容ができて非常にうれしいです。 また、グローバル関数とローカル関数でのエラーという初歩的な内容のエラーまで載せてしまい申し訳ございません。 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問