回答編集履歴

6

説明補足

2020/05/01 19:49

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -161,3 +161,21 @@
161
161
  main()
162
162
 
163
163
  ```
164
+
165
+
166
+
167
+ 追記: 解決策2の案を お勧めしない理由は、nametowidgetでは、動的に探索される為
168
+
169
+ dir(app) としても属性に button1, button2 は列挙されません。=> IDE等で補完候補に出ない
170
+
171
+ また、静的解析ツール等にとっても型の解らない属性になるので、デメリットになります。
172
+
173
+ 本当に必要な時以外は、記述が楽になるという理由だけでは採用しない方が良いです。
174
+
175
+
176
+
177
+ 紹介の意図としては、他にこのような(直接 pack/grid/placeを呼んでいる)コードを見かけた時に、
178
+
179
+ 後々参照の必要がないか、nametowidget()を通じて参照できるという点に留意して、
180
+
181
+ 参考にして頂けたらと思います。

5

説明修正

2020/05/01 19:49

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -54,7 +54,7 @@
54
54
 
55
55
  ----
56
56
 
57
- 解決策2: 名前を付けて `__getattr__` 経由でアクセスする
57
+ 解決策2: 名前を付けて `nametowidget()` 経由でアクセスする
58
58
 
59
59
 
60
60
 

4

nameを付ける方法の紹介

2020/05/01 18:47

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -47,3 +47,117 @@
47
47
  tk.Button(master,text="Button",command=command).place(x=110, y=110)
48
48
 
49
49
  ```
50
+
51
+
52
+
53
+
54
+
55
+ ----
56
+
57
+ 解決策2: 名前を付けて `__getattr__` 経由でアクセスする
58
+
59
+
60
+
61
+ お勧めという訳ではありませんが、別解として紹介。
62
+
63
+ nameを付けると、後から参照することもできます。
64
+
65
+
66
+
67
+ ```python
68
+
69
+ import tkinter as tk
70
+
71
+
72
+
73
+ class Application(tk.Frame):
74
+
75
+ def __init__(self,master):
76
+
77
+ super().__init__(master)
78
+
79
+ self.pack()
80
+
81
+
82
+
83
+ master.geometry("300x150")
84
+
85
+ master.title("ストップウォッチ")
86
+
87
+ master.config(bg="black")
88
+
89
+
90
+
91
+ self.playTime=False
92
+
93
+
94
+
95
+ #ボタンを設置 (name=を付ける。注意点は第一引数の親ウィジェット)
96
+
97
+ tk.Button(master,text="Start",name="button1",command=self.startButtonClick,width=10,bg="lightgreen").place(x=110, y=110)
98
+
99
+ tk.Button(master,text="Stop",name="button2",command=self.stopButtonClick,width=10,bg="red").place(x=210, y=110)
100
+
101
+
102
+
103
+ def __getattr__(self, key):
104
+
105
+ """
106
+
107
+ self.button1 とアクセスされた場合、name="button1" と作成した tk.Button を返します。
108
+
109
+
110
+
111
+ 今回は簡単な例なので関係ありませんが、
112
+
113
+ nameの部分は、実際には親ウィジェットからのpathになる点に注意。
114
+
115
+ 例えば、第一引数の親が master ではなく self だった場合は、self.nametowidget(key)
116
+
117
+ """
118
+
119
+ return self.master.nametowidget(key)
120
+
121
+
122
+
123
+ def startButtonClick(self):
124
+
125
+ if not self.playTime:
126
+
127
+ self.playTime=True
128
+
129
+ self.button1["bg"] = "red"
130
+
131
+ self.button2["bg"] = "lightgreen"
132
+
133
+
134
+
135
+ def stopButtonClick(self):
136
+
137
+ if self.playTime:
138
+
139
+ #測定終了
140
+
141
+ self.playTime=False
142
+
143
+ self.button1["bg"]="lightgreen"
144
+
145
+ self.button2["bg"] = "red"
146
+
147
+
148
+
149
+ def main():
150
+
151
+ win = tk.Tk()
152
+
153
+ app = Application(master=win)
154
+
155
+ app.mainloop()
156
+
157
+
158
+
159
+ if __name__ == "__main__":
160
+
161
+ main()
162
+
163
+ ```

3

説明文修正

2020/05/01 18:46

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -44,10 +44,6 @@
44
44
 
45
45
  ```
46
46
 
47
- # None が返るが、ウィジェットの実体は tkiner内部の tcl/tk 側で管理される為
48
-
49
- # tk.Button()が返すPython内のオブジェクトの寿命に関わらず、ボタンは存在し続けます。
50
-
51
47
  tk.Button(master,text="Button",command=command).place(x=110, y=110)
52
48
 
53
49
  ```

2

直接レイアウト関数を呼ぶ場合の説明補足

2020/05/01 18:25

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -34,9 +34,9 @@
34
34
 
35
35
  恐らく、このようなコードが混乱の原因だと思うのですが、
36
36
 
37
- 戻り値を**変数に受け取らない場合**、以下の記法自体は正し動作するコードで、
37
+ 戻り値を**変数に受け取らない場合**、以下の記法自体は使われるコードで、
38
38
 
39
- 標準ライブラリ内(idlelib)でもよく用いられています。
39
+ 標準ライブラリ内(idlelib)でも見かけられます。
40
40
 
41
41
  (ボタンやラベル等で後から参照する必要がない場合)
42
42
 

1

説明補足

2020/05/01 18:16

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -18,15 +18,15 @@
18
18
 
19
19
  ```python
20
20
 
21
- #ボタンを設置
21
+ #ボタンを設置
22
22
 
23
- self.button1 = tk.Button(master,text="Start",command=self.startButtonClick,width=10,bg="lightgreen")
23
+ self.button1 = tk.Button(master,text="Start",command=self.startButtonClick,width=10,bg="lightgreen")
24
24
 
25
- self.button1.place(x=110, y=110)
25
+ self.button1.place(x=110, y=110)
26
26
 
27
- self.button2 = tk.Button(master,text="Stop",command=self.stopButtonClick,width=10,bg="red")
27
+ self.button2 = tk.Button(master,text="Stop",command=self.stopButtonClick,width=10,bg="red")
28
28
 
29
- self.button2.place(x=210, y=110)
29
+ self.button2.place(x=210, y=110)
30
30
 
31
31
  ```
32
32
 
@@ -34,7 +34,7 @@
34
34
 
35
35
  恐らく、このようなコードが混乱の原因だと思うのですが、
36
36
 
37
- 戻り値を**変数に受け取らない場合は**、以下は正しく動作するコードで、
37
+ 戻り値を**変数に受け取らない場合は**、以下の記法自体は正しく動作するコードで、
38
38
 
39
39
  標準ライブラリ内(idlelib)でもよく用いられています。
40
40
 
@@ -44,8 +44,10 @@
44
44
 
45
45
  ```
46
46
 
47
- tk.Button(master,text="Start",command=self.startButtonClick,width=10,bg="lightgreen").place(x=110, y=110)
47
+ # None が返るが、ウィジェットの実体は tkiner内部の tcl/tk 側で管理される為
48
48
 
49
+ # tk.Button()が返すPython内のオブジェクトの寿命に関わらず、ボタンは存在し続けます。
49
50
 
51
+ tk.Button(master,text="Button",command=command).place(x=110, y=110)
50
52
 
51
53
  ```