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

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

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

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

Python

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

Q&A

解決済

3回答

2815閲覧

tkinterで入力した値をfor文で変数に代入する方法

surphy

総合スコア101

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/01/12 03:44

編集2020/01/12 04:37

GUIを作成しています。

入力した値を変数にいれていきたいのですが、今は次のようにひたすら書いています。

python

1 x0 = int(entries['x0'].get()) 2 y0 = int(entries['y0'].get()) 3 nx = int(entries['nx'].get()) 4 ny = int(entries['ny'].get()) 5 Px_small = int(entries['Px_small'].get()) 6 Py_small = int(entries['Py_small'].get()) 7 Px_large = int(entries['Px_large'].get()) 8 Py_large = int(entries['Py_large'].get())

このような書き方をfor文などですっきりできないかと思っているのですが、何か方法ありますでしょうか。

なお、https://teratail.com/questions/234591#reply-341552の質問の続きでもあります。

現在のコード全体は、次となっています。

python

1import sys 2import tkinter 3import numpy as np 4import matplotlib.pyplot as plt 5 6 7labels = 'x0', 'y0', 'nx', 'ny', 'Px_small', 'Py_small', 'Px_large', 'Py_large' 8entries = {} 9 10root = tkinter.Tk() 11root.title(u"GUI_test") #name 12 13for label in labels: 14 tkinter.Label(text=label).pack() #make label 15 entries[label] = tkinter.Entry() #input 16 entries[label].pack() 17 if label=='x0' or label=='y0': 18 entries[label].insert(tkinter.END, 0) #set initial values 19 elif label=='Px_small' or label=='Py_small': 20 entries[label].insert(tkinter.END, 200) #set initial values 21 elif label=='Px_large' or label=='Py_large': 22 entries[label].insert(tkinter.END, 400) #set initial values 23 24 25def generate_xy(x0, y0, nx, ny, Px_small, Py_small, Px_large, Py_large): 26 x = [] 27 y = [] 28 for i in range(nx): 29 for j in range(ny): 30 x_center = x0 - i*Px_large 31 y_center = y0 - j*Py_large 32 x.append(x_center + Px_small/2) 33 y.append(y_center + Py_small/2) 34 x.append(x_center + Px_small/2) 35 y.append(y_center - Py_small/2) 36 x.append(x_center - Px_small/2) 37 y.append(y_center - Py_small/2) 38 x.append(x_center - Px_small/2) 39 y.append(y_center + Py_small/2) 40 return x, y 41 42 43def caliculate(): 44 x0 = int(entries['x0'].get()) 45 y0 = int(entries['y0'].get()) 46 nx = int(entries['nx'].get()) 47 ny = int(entries['ny'].get()) 48 Px_small = int(entries['Px_small'].get()) 49 Py_small = int(entries['Py_small'].get()) 50 Px_large = int(entries['Px_large'].get()) 51 Py_large = int(entries['Py_large'].get()) 52 x, y = generate_xy(x0, y0, nx, ny, Px_small, Py_small, Px_large, Py_large) 53 for label in labels: 54 print(label + ':' + entries[label].get()) 55 fig = plt.figure(figsize=(5,5)) 56 ax = fig.add_subplot(1,1,1) 57 ax.scatter(x,y) 58 ax.set_title('first scatter plot') 59 ax.set_xlabel('x') 60 ax.set_ylabel('y') 61 ax.set_ylim([-1000, 1000]) 62 ax.set_xlim([-1000, 1000]) 63 fig.show() 64 65 66tkinter.Button(text='Submit', command=caliculate).pack() 67 68root.mainloop() 69

------修正前の質問-------
variable_name = ['x', 'y']
というリストから、
x = 'x'
y = 'y'
と変数を定義したいです。

実際は、リストの要素が20くらいあるので、for文などで一気に変数に代入したいので、質問しています。

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

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

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

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

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

surphy

2020/01/12 04:13

アドバイスありがとうございます。 おっしゃる通りですね。 質問内容をこれから修正します。
guest

回答3

0

ベストアンサー

こんな書き方はいかが?
配列アクセスや属性アクセス(__getattr__)もできるようにクラスを作ってみました。
ただ、Entriesはmainloopから抜けるとget()できなくなるため、StringVar() を使うように変えた方がよさそうです。

python

1import sys 2import tkinter 3#import numpy as np 4#import matplotlib.pyplot as plt 5 6labels = dict(x0=0, y0=0, 7 nx='', ny='', 8 Px_small=200, Py_small=200, 9 Px_large=400, Py_large=400) 10 11class Entries: 12 13 def __init__(self): 14 self.entries = {} 15 16 def __setitem__(self, label, entry): 17 self.entries[label] = entry 18 19 def __getitem__(self, label): 20 return self.entries[label].get() 21 22 def __getattr__(self, name): 23 return self.entries[name].get() 24 25 26entries = Entries() 27 28root = tkinter.Tk() 29root.title("GUI_test") 30 31for label in labels: 32 tkinter.Label(text=label).pack() 33 entry = tkinter.Entry(text=label) 34 entry.pack() 35 entry.insert(tkinter.END, labels[label]) 36 entries[label] = entry 37 38def generate_xy(x0, y0, nx, ny, Px_small, Py_small, Px_large, Py_large): 39 x = [] 40 y = [] 41 for xi in range(nx): 42 for yi in range(ny): 43 x_center = x0 - xi*Px_large 44 y_center = y0 - yi*Py_large 45 x += [x_center + Px_small/2] * 4 46 y += [y_center + Py_small/2] * 4 47 return x, y 48 49 50def calculate(): 51 values = [int(entries[label]) for label in labels] 52 x, y = generate_xy(*values) 53 print(x) 54 print(y) 55 for label in labels: 56 print(label + ':' + entries[label]) 57 fig = plt.figure(figsize=(5,5)) 58 ax = fig.add_subplot(1,1,1) 59 ax.scatter(x,y) 60 ax.set_title('first scatter plot') 61 ax.set_xlabel('x') 62 ax.set_ylabel('y') 63 ax.set_ylim([-1000, 1000]) 64 ax.set_xlim([-1000, 1000]) 65 fig.show() 66 67 68tkinter.Button(text='Calculate', command=calculate).pack() 69 70root.mainloop()

投稿2020/01/12 05:39

編集2020/01/12 12:27
shiracamus

総合スコア5406

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

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

surphy

2020/01/13 03:42 編集

ご回答ありがとうございます。 辞書を使ってすっきり書けることがわかりました。勉強になります。 クラスについてはまだ使い慣れてなく、今読解しています。
shiracamus

2020/01/13 04:44

今回の内容ならクラス定義せずに直接.get()しても良かったですね。 クラス定義したことで entries['x0'] や entries.x0 で値が取れるようになってます。
guest

0

caliculate()の最初の部分

python

1def caliculate(): 2 x0 = int(entries['x0'].get()) 3 y0 = int(entries['y0'].get()) 4 nx = int(entries['nx'].get()) 5 ny = int(entries['ny'].get()) 6 Px_small = int(entries['Px_small'].get()) 7 Py_small = int(entries['Py_small'].get()) 8 Px_large = int(entries['Px_large'].get()) 9 Py_large = int(entries['Py_large'].get()) 10 x, y = generate_xy(x0, y0, nx, ny, Px_small, Py_small, Px_large, Py_large)

を、

python

1def caliculate(): 2 x, y = generate_xy(**{key: int(entries[key].get()) for key in labels})

に置き換えることができると思います。

投稿2020/01/12 12:20

bsdfan

総合スコア4571

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

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

surphy

2020/01/13 03:44

ご回答をどうもありがとうございます。 entriesは辞書型なので、それを利用してfor文で抜き出しているということであっていますか?
bsdfan

2020/01/13 04:10

entriesから、内包表記で、値がintに変換された辞書を作り直しています。 それに**をつけて関数に渡すことで、辞書の中身が展開されて、関数が呼ばれています。
guest

0

これでどうでしょう?

Python

1variable_name = ['x', 'y'] 2 3for i in variable_name: 4 locals()[str(i)] = str(i) 5 6print(x) 7print(y)

すでにリストがあるので、
リストのインデックスで呼び出した方が
扱いやすいのではないかと思うのですが。

投稿2020/01/12 04:15

3109

総合スコア80

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

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

surphy

2020/01/13 02:18 編集

ご回答をありがとうございます。 やりたいことが教えてくださった方法でできました。 質問を修正したのですが、今回の目的でも、教えていただいた方法で問題ないでしょうか。 コメントいただけたら幸いです。
bsdfan

2020/01/12 11:51

locals()の戻り値への代入では変数は作成されないはずです。
shiracamus

2020/01/12 12:14

この場合の locals() はグローバル空間で呼び出しているため、 globals() と同じグローバル変数辞書が返ってきます。グローバル変数辞書では変数作成できます。 locals() を globals() に変更する方がいいとは思います。
bsdfan

2020/01/12 12:23

siracamusさん、そこは気が付きませんでした。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問