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

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

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

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

Tkinter

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

Q&A

解決済

2回答

1438閲覧

for文で同じ名前のインスタンスの作成に関する質問

popy

総合スコア9

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2022/05/31 09:59

Pythonにてtkinterを利用したGUI作成の勉強をしております。
初学者でclassの使い方も十分に理解できておらず勉強しながら習得を進めています。
今回教えていただきたいのはclassに関することです。

作りたいサンプルはTkinterで複数のラベルを配置するプログラムです。
ネットで調べながら作成したコードは以下の通りです。
実行すると、for文を使って3つの「猫」というラベルが生成されています。
この後、ボタンを配置して任意のラベルの位置を移動させるコードに改造しようと考えております。
また、インスタンスも50個程度まで作成できるように拡張させる予定です。

ここで疑問なのですが、私のコードはfor文をつかってroot2という名前のインスタンスを3つ作りました。
このままですと、3つのインスタンスの内、同じ名前でインスタンスを作成しているので任意のラベルを移動することができないのではないかと思います。
ですが、コードを実行してもエラーが発生することなく実行できます。

そこで質問ですが、

質問①インスタンスの生成をfor文で、同一名前のインスタンスを複数作成することは一般的なのでしょうか?
質問②私の作成したコードで、3つ作成したラベルの内、1つを特定して、例えば.placeで位置座標変更を変更するなどの処理が可能でしょうか。
質問③もし、複数のインスタンスを生成し、それぞれを名前で区別したい場合、常套手段があれば教えてください。

import tkinter as tk class MAKE_GUI(tk.Frame): def __init__(self,master=None): tk.Frame.__init__(self,master=None) self.master.title('サンプル') self.master.geometry('600x900') self.TSUIKA=TSUIKA class TSUIKA: ITEM_LIST_KAZU=0 def __init__(self,master=None): self.x_zahyou=10 self.y_zahyou=50+30*int(TSUIKA.ITEM_LIST_KAZU) label2 = tk.Label(master, text='猫', bg='white') label2.place(x = self.x_zahyou , y = self.y_zahyou) TSUIKA.ITEM_LIST_KAZU+=1 def main(): root=MAKE_GUI() #インスタンスをforで複数つくるのはプログラミング上問題あるのでしょうか? for i in range(3): root2=TSUIKA() root.mainloop() print('finish') if __name__ == '__main__': main()

イメージ説明

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

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

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

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

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

guest

回答2

0

ベストアンサー

すでに回答付いてますが、ちょっと気になったことを。

「 私のコードはfor文をつかってroot2という名前のインスタンスを3つ作りました。」という理解は間違えています。

python

1root2=TSUIKA()

こう書いたとき、TUIKAクラスのインスタンスが作られますが、それは、プロセスの中のどこかに作られています。いわゆる名前はありません
変数 root2 は何をしているのかというと、その作られたインスタンスを「指して」います。(束縛されているというのが正しいです)
ループが回って、次のインスタンスが作られると、root2はその新しく作られたインスタンスを指すようになります。
最初に作られたインスタンスは存在したままですが、指している変数が無いので、そこにアクセスすることができません。

ちなみに、普通のpythonのオブジェクト(インスタンス)は、指している変数が無くなると、システムのガベージコレクタ(gc)が回収して破棄してくれます。
tkinterのラベルなどのオブジェクトは、tkinterそのものが保持しているので勝手に消されたりはしないようになっています。

このように、変数に入れることは名前を点けているわけではないので、指ししめす場所さえあればいいので、y_waiwaiさんの回答の質問にあるように、リストに入れてやればいいのです。

python

1 tsuika_list = [] 2 for i in range(3): 3 tsuika_list.append(TSUIKA())

こんな感じです。 これで、あとから、tsuika_list[0]のようにアクセスできます。

あと、TSUIKAクラスの中の__init__関数の中でラベルを作っていますが、このラベルが「label2」という一時的な変数に入っているので、後からアクセスできません。
これも、x,y のように、いんすたんす変数 self.label などとしておけば、 tsuka_list[0].label という形でアクセスできるようになります。

投稿2022/05/31 12:34

TakaiY

総合スコア12767

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

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

0

root2=TSUIKA()

これでは、インスタンスをroot2という変数に次々上書きしているため、最後に作ったものしかroot2に入りません
最後に作ったものしか後で操作できないってことになるかと

投稿2022/05/31 10:32

y_waiwai

総合スコア87774

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

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

popy

2022/05/31 11:43

回答ありがとうございます。 forをつかわずにベタ打ちで CAT1=TSUIKA() CAT2=TSUIKA() CAT3=TSUIKA() とコードを修正して対応いたします。
y_waiwai

2022/05/31 11:44

for文で回して、リストに入れればいいですやん
popy

2022/05/31 12:55

TakaiY様 classの解説ありがとうございました。インスタンスは名前を必ずついているものだと誤解しておりました。forで同じ変数に上書きをしたら、以前のインスタンスにアクセスできなくなる理屈もTakaiY様の解説で理解できました。サンプルも非常に分かりやすく助かりました。また、質問には書いていなかったのですが、ラベルにアクセスできなかったことも困っており、それに対する対処法がありがたかったです。
popy

2022/05/31 12:56

y_waiwai様 情報ありがとうございました。リストを用いた記述に修正してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問