回答編集履歴

1

追記

2023/05/29 14:46

投稿

meg_
meg_

スコア10602

test CHANGED
@@ -1 +1,294 @@
1
1
  ``root.mainloop()``を``button.grid(row=3, column=0) ``の後ろに移動すれば良いかと思います。
2
+
3
+ ---
4
+ ```Python
5
+ import pandas as pd
6
+ import tkinter as tk
7
+ import numpy as np
8
+ import matplotlib.pyplot as plt
9
+ from tkinter import ttk
10
+ from tkinter import filedialog
11
+
12
+ def Input():
13
+ root = tk.Tk()
14
+ root.title('Lens Data Editor')
15
+ root.geometry('+800+200') # ウィンドウの表示位置を指定
16
+
17
+ frame = ttk.Frame(root)
18
+ frame.grid(row=0, column=0)
19
+
20
+ # 項目をつくる
21
+ items = ['No.', '曲率半径R', '肉厚間隔T', '硝材', '有効半径']
22
+ for i in range(0, len(items)):
23
+ label_item = ttk.Label(frame, text=items[i])
24
+ label_item.grid(row=0, column=i)
25
+
26
+ n = 20 # 行数
27
+ # 項目1
28
+ items1 = [0] * n
29
+ for i in range(0, n):
30
+ items1[i] = tk.IntVar()
31
+ item1 = ttk.Entry(frame, textvariable=items1[i], width=10)
32
+ item1.grid(row=i+1, column=0)
33
+ item1.insert(i, i)
34
+
35
+ # 項目2
36
+ items2 = [0] * n
37
+ for i in range(0, n):
38
+ items2[i] = tk.DoubleVar()
39
+ item2 = ttk.Entry(frame, textvariable=items2[i], width=10)
40
+ item2.grid(row=i+1, column=1)
41
+
42
+ # 項目3
43
+ items3 = [0] * n
44
+ for i in range(0, n):
45
+ items3[i] = tk.DoubleVar()
46
+ item3 = ttk.Entry(frame, textvariable=items3[i], width=10)
47
+ item3.grid(row=i+1, column=2)
48
+
49
+ # 項目4
50
+ items4 = [0] * n
51
+ for i in range(0, n):
52
+ items4[i] = tk.DoubleVar()
53
+ item4 = ttk.Entry(frame, textvariable=items4[i], width=10)
54
+ item4.grid(row=i+1, column=3)
55
+
56
+ # 項目5
57
+ items5 = [0] * n
58
+ for i in range(0, n):
59
+ items5[i] = tk.DoubleVar()
60
+ item5 = ttk.Entry(frame, textvariable=items5[i], width=10)
61
+ item5.grid(row=i+1, column=4)
62
+
63
+
64
+ # Enterが押された時の処理
65
+ def move_to_next_row(event):
66
+ # current position
67
+ info = event.widget.grid_info()
68
+ r, c = info['row'], info['column']
69
+ # number of rows
70
+ nrows = frame.grid_size()[1]
71
+ # move to next row
72
+ r = (r + 1) if r < nrows-1 else r
73
+ frame.grid_slaves(row=r, column=c)[0].focus_set()
74
+
75
+ for w in frame.winfo_children():
76
+ if isinstance(w, ttk.Entry):
77
+ w.bind('<Return>', move_to_next_row)
78
+ w.bind('<Down>', move_to_next_row)
79
+
80
+
81
+ # 上が押された時の処理
82
+ def move_to_prev_row(event):
83
+ # current position
84
+ info = event.widget.grid_info()
85
+ r, c = info['row'], info['column']
86
+ # number of rows
87
+ # nrows = frame.grid_size()[1]
88
+ # move to next row
89
+ r = (r - 1) if r > 1 else r
90
+ frame.grid_slaves(row=r, column=c)[0].focus_set()
91
+
92
+ for w in frame.winfo_children():
93
+ if isinstance(w, ttk.Entry):
94
+ w.bind('<Up>', move_to_prev_row)
95
+
96
+
97
+ # 右が押された時の処理
98
+ def move_to_right_row(event):
99
+ # current position
100
+ info = event.widget.grid_info()
101
+ r, c = info['row'], info['column']
102
+ # number of columns
103
+ ncolumns = frame.grid_size()[1]
104
+ # move to next row
105
+ # c = (c + 1) if c > 1 else c
106
+ c = (c + 1) if c < ncolumns-1 else c
107
+ frame.grid_slaves(row=r, column=c)[0].focus_set()
108
+
109
+ for w in frame.winfo_children():
110
+ if isinstance(w, ttk.Entry):
111
+ w.bind('<Right>', move_to_right_row)
112
+
113
+
114
+ # 左が押された時の処理
115
+ def move_to_left_row(event):
116
+ # current position
117
+ info = event.widget.grid_info()
118
+ r, c = info['row'], info['column']
119
+ # number of columns
120
+ # ncolumns = frame.grid_size()[1]
121
+ # move to next row
122
+ c = (c - 1) if c > 1 else c
123
+ # c = (c + 1) if c < ncolumns-1 else c
124
+ frame.grid_slaves(row=r, column=c)[0].focus_set()
125
+
126
+ for w in frame.winfo_children():
127
+ if isinstance(w, ttk.Entry):
128
+ w.bind('<Left>', move_to_left_row)
129
+
130
+
131
+
132
+ # 実行ボタン
133
+ def execute():
134
+ #これまでの入力をリストに入れる
135
+ table_data = []
136
+ for i in range(0, n):
137
+ table_data.append([items1[i].get(),
138
+ items2[i].get(),
139
+ items3[i].get(),
140
+ items4[i].get(),
141
+ items5[i].get()])
142
+ # pandas dataframeに変換
143
+ df = pd.DataFrame(table_data, columns=['No.', '曲率半径R', '肉厚間隔T', '硝材', '有効径'])
144
+
145
+ # 結果表示
146
+ Output(df)
147
+
148
+ button = ttk.Button(root, text='計算', padding=5, command=execute)
149
+ button.grid(row=1, column=0)
150
+
151
+ #utton = ttk.Button(root, text='計算', padding=5, command=execute)
152
+ #utton.grid(row=3, column=0)
153
+
154
+ # レンズ描画
155
+ def lens_draw():
156
+
157
+ # 新しいルートウィンドウを作成
158
+ root2 = tk.Tk()
159
+ root2.title('Lens Drawing')
160
+ root2.geometry('600x400') # ウィンドウのサイズを指定
161
+
162
+ # ウィンドウの内容を配置するフレームを作成
163
+ frame2 = ttk.Frame(root2)
164
+ frame2.grid(row=0, column=0)
165
+
166
+ max = 0
167
+ length = 0
168
+
169
+ for i in range(0, n):
170
+ if(items5[i].get()>0):
171
+ angle_1 = np.arcsin(items5[i].get()/items2[i].get())
172
+ #angle_2 = np.arcsin(float(items5[i].get())/float(items2[i].get()))
173
+ tmp = items5[i].get()
174
+ if(tmp>max):
175
+ max = tmp
176
+
177
+ # Canvasを置く
178
+ canvas = tk.Canvas(root2, width = 600, height = 400, bg="white")
179
+ canvas.place(x = 0, y = 0)
180
+ #canvas.translate(width, height/2)
181
+
182
+ # 曲率半径を描く
183
+ if(items2[i].get()>0):
184
+ canvas.create_arc(length, items2[i].get(), length+2*items2[i].get(), -items2[i].get(), start=180-angle_1, extent=180+angle_1, style=tk.ARC)
185
+ if(items2[i].get()<0):
186
+ canvas.create_arc(length+2*items2[i].get(), -items2[i].get(), length, items2[i].get(), start=360+angle_1, extent=-angle_1, style=tk.ARC)
187
+ if(items2[i].get()==0):
188
+ canvas.create_line(length, items5[i].get(), length, items5[i].get())
189
+ #fig, ax = plt.subplots()
190
+ #ax.add_patch(plt.arc(float(items2[i]), length + float(items2[i]), angle_1, angle_2))
191
+ length = length + items3[i].get()
192
+
193
+ #ax.set_xlim([0, length])
194
+ #ax.set_ylim([-max, max])
195
+ #plt.axis('equal') # アスペクト比を保持
196
+ #plt.grid(True) # グリッド線を表示(任意)
197
+ #plt.show()
198
+
199
+ # ルートウィンドウをメインループで表示
200
+ root2.mainloop()
201
+
202
+ button = ttk.Button(root, text='描画', padding=5, command=lens_draw)
203
+ button.grid(row=2, column=0)
204
+
205
+ # root.mainloop()
206
+
207
+
208
+ # 途中経過の出力
209
+ def middle():
210
+
211
+ max = 0
212
+ length = 0
213
+
214
+ for i in range(0, n):
215
+ if(items5[i].get()>0):
216
+ angle_1 = np.arcsin(items5[i].get()/items2[i].get())
217
+ #angle_2 = np.arcsin(float(items5[i].get())/float(items2[i].get()))
218
+ tmp = items5[i].get()
219
+ if(tmp>max):
220
+ max = tmp
221
+
222
+ print(i+"回目")
223
+ print("items1[" + str(i) + "]:" + str(items1[i].get()))
224
+ print("items2[" + str(i) + "]:" + str(items2[i].get()))
225
+ print("items3[" + str(i) + "]:" + str(items3[i].get()))
226
+ print("items4[" + str(i) + "]:" + str(items4[i].get()))
227
+ print("items5[" + str(i) + "]:" + str(items5[i].get()))
228
+ print("angle_1:" + str(angle_1))
229
+
230
+
231
+ button = ttk.Button(root, text='途中', padding=5, command=middle)
232
+ button.grid(row=3, column=0)
233
+
234
+ root.mainloop()
235
+
236
+ def Output(df):
237
+ root = tk.Tk()
238
+ root.title('Lens Data Output')
239
+
240
+ frame = ttk.Frame(root, padding=5)
241
+ frame.grid(row=0, column=0)
242
+
243
+ # ツリービューの作成
244
+ tree = ttk.Treeview(frame)
245
+
246
+ # 列インデックスの作成
247
+ tree['columns'] = (0,1,2,3,4)
248
+ # 表スタイルの設定(headingsは通常の表形式)
249
+ tree['show'] = 'headings'
250
+ # 各列の設定(インデックス,オプション(今回は幅を指定))
251
+ for i in range(0,5):
252
+ tree.column(i,width=100)
253
+
254
+ # 各列のヘッダー設定(インデックス,テキスト)
255
+ tree.heading(0, text='No.')
256
+ tree.heading(1, text='曲率半径R')
257
+ tree.heading(2, text='肉厚間隔T')
258
+ tree.heading(3, text='硝材')
259
+ tree.heading(4, text='有効径')
260
+
261
+ for i in range(0, len(df)):
262
+ item1 = df.iloc[i][0]
263
+ item2 = df.iloc[i][1]
264
+ item3 = df.iloc[i][2]
265
+ item4 = df.iloc[i][3]
266
+ item5 = df.iloc[i][4]
267
+
268
+ # レコードの作成
269
+ # 1番目の引数-配置場所(表形式の表示ではブランクとする)
270
+ # 2番目の引数-end:表の配置順序を最下部に配置
271
+ # (行インデックス番号を指定することもできる)
272
+ # 3番目の引数-values:レコードの値をタプルで指定する
273
+ tree.insert('', 'end', values=(item1, item2, item3, item4, item5))
274
+
275
+ # ツリービューの配置
276
+ tree.grid(row=0)
277
+
278
+ # 保存ボタン
279
+ def save():
280
+ fld = tk.filedialog.askdirectory(initialdir = 'C:')
281
+ df.to_csv(fld + '/table.csv', encoding='shift-jis', index=False)
282
+
283
+ button = ttk.Button(root,
284
+ text='保存',
285
+ command=save)
286
+ button.grid(row=2, pady=5)
287
+
288
+ root.mainloop()
289
+
290
+ if __name__ == '__main__':
291
+ Input()
292
+ ```
293
+ 上記コードで下記が表示されました。
294
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-05-29/4155ca4e-cdfb-4a3a-be24-5316640ee2c3.png)