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

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

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

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Tkinter

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

Python

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

Q&A

解決済

1回答

1521閲覧

python:動的にtkinterのStringVar()変数作成法

akiteru

総合スコア18

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Tkinter

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

Python

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

0グッド

1クリップ

投稿2021/09/01 04:21

前提・実現したいこと

pythonとsqlite3で自分用の住所録作成中。tkinterのentryウェジェットにStringVar()型の変数をテーブルのフィールド名と関連した名称で動的に作成し表示しようと思いますがエラーが出て表示できません。
下記コードのtest_1.pyは正常に動作し「田中」が表示されます。test_2.py及び test_3.pyではprint(var_name)又はprint(self.var_name)部分で下記エラー発生。
エラー行前までは正常に動作しそれぞれの値が表示されます。test_1.pyとtest_2.pyの違いが原因の「もと」と思いますが、この違いが理解できません

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

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

エラーメッセージ test_2.pyでのエラー 例外が発生しました: NameError name 'var_name' is not defined test_3.pyでのエラー 例外が発生しました: AttributeError 'Myclass' object has no attribute 'var_name'

該当のソースコード

ソースコード # ***** test_1.py ***** import tkinter as tk import tkinter.ttk as ttk root = tk.Tk() # データベーステーブルのフィールド名をキーとした辞書型 tbl_dict={} tbl_dict["id"] = 1 tbl_dict["name"] = 2 # データベーステーブルのフィールド名をキーとし、 # これと関連したtkinterのStringVar()型の変数名の辞書型 var_dict = {} for key in tbl_dict: # キーに関連した変数名 var_dict[key] = "var_" + key # StringVar()型の変数作成 vars()[var_dict[key]] = tk.StringVar() # キーを"name"に指定、そのStringVar()型変数のに”田中”を代入 key = "name" vars()[var_dict[key]] = "田中" # 代入値を表示させる print(vars()[var_dict[key]]) print(var_dict[key]) print(var_name) # ***** test_2.py ***** import tkinter as tk import tkinter.ttk as ttk def test(): root = tk.Tk() # データベーステーブルのフィールド名をキーとした辞書型 tbl_dict={} tbl_dict["id"] = 1 tbl_dict["name"] = 2 # データベーステーブルのフィールド名をキーとし、 # これと関連したtkinterのStringVar()型の変数名の辞書型 var_dict = {} for key in tbl_dict: # キーに関連した変数名 var_dict[key] = "var_" + key # StringVar()型の変数作成 vars()[var_dict[key]] = tk.StringVar() # キーを"name"に指定、そのStringVar()型変数のに”田中”を代入 key = "name" vars()[var_dict[key]] = "田中" # 代入値を表示させる print(vars()[var_dict[key]]) print(var_dict[key]) print(type(var_dict[key])) print(var_name) test() # ***** test_3.py ***** import tkinter as tk import tkinter.ttk as ttk class Myclass(): def __init__(self,a,b): root = tk.Tk() # データベーステーブルのフィールド名をキーとした辞書型 self.tbl_dict={} self.tbl_dict["id"] = a self.tbl_dict["name"] = b def dict_make(self): # データベーステーブルのフィールド名をキーとし、 # これと関連したtkinterのStringVar()型の変数名の辞書型 self.var_dict = {} for key in self.tbl_dict: # キーに関連した変数名 self.var_dict[key] = "self.var_" + key # StringVar()型の変数作成 vars()[self.var_dict[key]] = tk.StringVar() def var_print(self): # キーを"name"に指定、そのStringVar()型変数のに”田中”を代入 key = "name" vars()[self.var_dict[key]] = "田中" print(vars()[self.var_dict[key]]) print(self.var_dict[key]) print(self.var_name) # 代入値を表示させる ex = Myclass(1,2) ex.dict_make() ex.var_print()

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

たいしてよく知っているわけではありませんが、コメントを2つ。

・varsは基本的には参照するために用意されているので、これを変更することは想定されていないように思います。

varsのリファレンス

書き込みが制限されている場合があるとありますので、それに該当しているのではないでしょうか。

・変数名を動的に生成したいという場合は、その変数名を大抵リストやdictに置き換えるのが正しい方法です。
dictで代替できない理由がありますか?


self.var_dict{"id":"self.var_id, "neme":"self.var_name"}と変数名の文字列を要素にした辞書型データは出来るのですが、これから変数名として取り出し、self.var_name="田中"と左辺が文字列でない状態にする方法が判りません。

dictに変数名を格納するのではありません。

又逆にself.var_dict["name"] = self.「var_+フィールド名 "name"」と直接文字列でない変数名を合成する方法が判りません。異常からvars()を見つけた次第です。上記の様に変数名を直接合成して作成する方法は有のでしょうか?

変数名を合成するのでもありません。

StringVarは変数に入れなければならないわけではないのです。

StringVarそのものをdictに入れればいいのです。

python

1var_dict['name'] = StringVar() 2var_dict['id'] = StringVar()

さらにこれを複数持ちたいのであれば、さらにリストやdictに入れます。

python

1 2button_dict{'OK'} = {'name': StringVar(), 3 'id!: StringVar()} 4button_dict{'Cansel'} = {'name': StringVar(), 5 'id!: StringVar()}

こんな感じです。


a1,a2,a3...、b1,b2,b3...、さらに...、等の不特定名称の変数を動的に作成し、これを格納する辞書型の作成方法は有るのでしょうか?

番号付きの変数を作りたくなった場合は、それは、リストに入れます。
というか、そういう情報を格納するためにリストがあるのです。

python

1a1 = 10 2a2 = 20 3a3 = 30 4...

としたければ、

python

1a = [] 2a.append(0) 3a.append(10) 4a.append(20) 5a.append(30) 6...

こうすれば、

python

1for i in range(4): 2 print(a[i])

のようにアクセスできます。

この方法だと、リストの生成が面倒だという場合、データの設計が間違えている可能性が高いです。たとえば今回のような場合は、

python

1a = [] 2for i in range(4): 3 a.append(i * 10)

と書くことができます。こういう規則が無いのであれば、元データをファイルに作っておいて読む手もあります。

数字が付いているとは言っても、 1,2,3,11,12,13...のように飛び飛びにしたい場合もあるでしょう。そういうう場合は、2次元配列にするとか、番号をキーとしたdictを使います。
アクセスするときも、1けためと2けためで別に生成するとになるでしょう。

投稿2021/09/01 05:19

編集2021/09/02 07:52
TakaiY

総合スコア12832

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

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

akiteru

2021/09/01 08:48

ご指摘ありがとうございます。初心者で右往左往の状態です。 ネットで調べるとご指摘の様にdictで指定するのが良いとあります。self.var_dict{"id":"self.var_id, "neme":"self.var_name"}と変数名の文字列を要素にした辞書型データは出来るのですが、これから変数名として取り出し、self.var_name="田中"と左辺が文字列でない状態にする方法が判りません。又逆にself.var_dict["name"] = self.「var_+フィールド名 "name"」と直接文字列でない変数名を合成する方法が判りません。異常からvars()を見つけた次第です。上記の様に変数名を直接合成して作成する方法は有のでしょうか?
akiteru

2021/09/02 01:34

有難うございます。まさに私にとっては「ミラクルマジック」、まづは解決です。ついでと言っては失礼ですが同様の疑問にご教授いただけますか。a1,a2,a3***、b1,b2,b3***、さらに***、等の不特定名称の変数を動的に作成し、これを格納する辞書型の作成方法は有るのでしょうか?
TakaiY

2021/09/02 07:52

追記しました。
akiteru

2021/09/03 02:56

ご教授ありがとうございました。昔の映画の「おぬしも知恵者じゃのう」の感じです。pythonの言語レファランスはチンプンカンプンで、ひたすら「python入門」の様なページからパクッテいるとなかなか大本が理解できていないのは痛感しているのですが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問