teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

一部修正

2020/09/17 11:59

投稿

nto
nto

スコア1438

answer CHANGED
@@ -85,7 +85,7 @@
85
85
 
86
86
  ##### Button Event
87
87
  def LabelChange(self):
88
- # 同じtextvariableを使用している為、ループする必要はなく1度の更新で全て反映できる
88
+ # 行数でループするのではなく直接buttonを格納しているリストから更新する事簡潔済む
89
89
  if self.var.get():
90
90
  [label.configure(text='削除') for label in self.InsertAndRemoveStatus]
91
91
  else:

2

修正

2020/09/17 11:59

投稿

nto
nto

スコア1438

answer CHANGED
@@ -1,1 +1,184 @@
1
+ 日本語コードが読みづらく、1から作り直させていただきました。
2
+ (classによるフォーマットで申し訳御座いません。)
3
+
4
+ データは辞書形式で、Entryウィジェットなどもリストで管理しているので各種応用がしやすいと思います。
5
+ ページを切り替えた場合のデータの保存も
6
+ 遷移時のEntry取得→辞書を更新→Entryの中身削除→辞書から次のページデータを表示
7
+ という形で再現しております。
8
+ ```python
9
+ import os
10
+ import csv
11
+ import pandas as pd
12
+ import tkinter as tk
13
+ from tkinter import messagebox
14
+ from tkinter import filedialog
15
+
16
+ class MainWindow(tk.Frame):
17
+ def __init__(self, master):
18
+ super().__init__(master)
19
+ self.master.title('Hello, World!')
20
+ self.master.geometry('650x300')
21
+
22
+ # 各種事前定義
23
+ self.data_dic = {'No': ['1','2','3','4','5','6','7','8','9','10','11'],
24
+ '姓': ['渡邊','柳川','清野','根本','阿部','稲田','木内','三宅','石村','本郷','山田'],
25
+ '名': ['沙樹','和臣','菜緒','駿斗','亜依','和徳','喜雄','美南','比呂','香帆','比呂'],
26
+ '性別': ['女','男','女','男','女','男','男','女','男','女','男'],
27
+ '生年月日': ['1988/07/15','1966/09/04','1979/06/08','1992/03/14','1977/04/04',
28
+ '1963/11/06','1972/08/21','1992/11/30','1967/12/07','1965/03/20','1977/04/04']
29
+ }
30
+ self.colum = 3
31
+ self.title = [key for key in self.data_dic.keys()]
32
+ self.tx_data = [list() for i in range(len(self.title))]
33
+ self.InsertAndRemoveStatus = []
34
+ self.pageid = 0
35
+
36
+ # 各種ウィジェット生成
37
+ self.CreateWidget()
38
+
39
+ ##### メインとなるウィジェットの生成
40
+ def CreateWidget(self):
41
+ ##############################
42
+ # Label及びEntryの生成
43
+ y = 50
44
+ x = 140
45
+ for i in self.title:
46
+ tk.Label(self.master, text=i).place(x=x, y=y)
47
+ x += 80
48
+
49
+ y = 80
50
+ for i in range(self.colum):
51
+ x = 140
52
+ for e, box in enumerate(self.tx_data):
53
+ width = 10
54
+ if e == 4:
55
+ width = 14
56
+ obj = tk.Entry(self.master, width=width)
57
+ obj.place(x=x, y=y)
58
+ box.append(obj)
59
+ x += 80
60
+ y += 31
61
+
62
+ ##############################
63
+ # 辞書データをEntryに挿入していく
64
+ for (key, value), box in zip(self.data_dic.items(), self.tx_data):
65
+ for data, widget in zip(value, box):
66
+ widget.insert(tk.END, data)
67
+
68
+ ##############################
69
+ # Button関連の生成
70
+ self.var = tk.BooleanVar()
71
+ tk.Checkbutton(variable=self.var, text="挿入 / 削除",command =self.LabelChange).place(x=40, y=50)
72
+
73
+ x = 50
74
+ y = 78
75
+ for i in range(self.colum):
76
+ obj = tk.Button(self.master, width=10, text='挿入')
77
+ obj.place(x=x, y=y)
78
+ self.InsertAndRemoveStatus.append(obj)
79
+ y += 30
80
+
81
+ button_data = {'クリア':[25, self.FieldClear], '読込':[130, self.DataRead], '保存': [200, self.DataSave],
82
+ '前ボタン': [330, self.PreviousPage], '次ボタン':[400, self.NextPage]}
83
+ for key, value in button_data.items():
84
+ tk.Button(self.master, text=key, command=value[1]).place(width=50, x=value[0], y=250)
85
+
86
+ ##### Button Event
87
+ def LabelChange(self):
88
+ # 同じtextvariableを使用している為、ループする必要はなく1度の更新で全てに反映できる
89
+ if self.var.get():
90
+ [label.configure(text='削除') for label in self.InsertAndRemoveStatus]
91
+ else:
92
+ [label.configure(text='挿入') for label in self.InsertAndRemoveStatus]
93
+
94
+ def NextPage(self):
95
+ self.TemporaryMemory()
96
+ self.FieldClear()
97
+ self.pageid += 1
98
+ self.EntryLoading()
99
+
100
+ def PreviousPage(self):
101
+ # 真偽値を測ってページidが0ならば処理を中断+エラーメッセージ
102
+ if self.pageid == 0:
103
+ messagebox.showerror('エラー', 'これ以上は前に戻れません')
104
+ return
105
+
106
+ self.TemporaryMemory()
107
+ self.FieldClear()
108
+ self.pageid -= 1
109
+ self.EntryLoading()
110
+
111
+ def EntryLoading(self):
112
+ for (key, value), box in zip(self.data_dic.items(), self.tx_data):
113
+ for widget, data in zip(box, value[self.pageid*self.colum: self.pageid*self.colum+self.colum]):
114
+ widget.insert(tk.END, data)
115
+
116
+ def DataRead(self):
117
+ fTyp = [('', '.csv')]
118
+ iDir = os.path.abspath(os.path.dirname(__file__))
119
+ file_name = filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)
120
+
121
+ # 真偽値を測りTrueの場合に読み込み処理、self.data_dicの内容を書き換える
122
+ # pageidもリセットする
123
+ if file_name:
124
+ self.pageid = 0
125
+ df = pd.read_csv(file_name, encoding='shift_jis', header=None)
126
+ df = df.fillna('')
127
+ self.FieldClear()
128
+ for i in df:
129
+ dic = {}
130
+ tmp = []
131
+ for e, data in enumerate(df[i]):
132
+ if e == 0:
133
+ header = data
134
+ else:
135
+ tmp.append(data)
136
+ self.data_dic[header] = tmp
137
+
138
+ for (key, value), box in zip(self.data_dic.items(), self.tx_data):
139
+ for data, widget in zip(value, box):
140
+ widget.insert(tk.END, data)
141
+
142
+ def DataSave(self):
143
+ fTyp = [('', '.csv')]
144
+ iDir = os.path.abspath(os.path.dirname(__file__))
145
+ file_name = filedialog.asksaveasfilename(filetypes=fTyp, initialdir=iDir)
146
+
1
- `正常動作していない部分があった為修正中`
147
+ # 保存時拡張子が入力されていない場合に拡張子を補完
148
+ if '.csv' not in file_name:
149
+ file_name = file_name + '.csv'
150
+ # 真偽値を測り、Trueの場合に書き込み処理、csv.writerを使用しlinetarminatorで行末を改行指定
151
+ if file_name:
152
+ self.TemporaryMemory()
153
+ with open(file_name, mode='w') as csvfile:
154
+ writer = csv.writer(csvfile, lineterminator='\n')
155
+ writer.writerow([key for key in self.data_dic.keys()])
156
+ for index in range(len(self.data_dic['No'])):
157
+ word = []
158
+ for values in self.data_dic.values():
159
+ word.append(values[index])
160
+ writer.writerow(word)
161
+ messagebox.showinfo('書き込み完了', f'{file_name}に保存しました')
162
+
163
+ def FieldClear(self):
164
+ # Entryウィジェット内の入力された文字列を全て消去
165
+ for box in self.tx_data:
166
+ for data in box:
167
+ data.delete(0, tk.END)
168
+
169
+ def TemporaryMemory(self):
170
+ keys = [key for key in self.data_dic.keys()]
171
+ for e, box in enumerate(self.tx_data):
172
+ for n, widget in enumerate(box):
173
+ data = widget.get()
174
+ try:
175
+ self.data_dic[keys[e]][n+self.pageid*self.colum] = data
176
+ except:
177
+ pass
178
+
179
+
180
+ if __name__ == '__main__':
181
+ root = tk.Tk()
182
+ window = MainWindow(master = root)
183
+ window.mainloop()
184
+ ```

1

修正

2020/09/17 11:40

投稿

nto
nto

スコア1438

answer CHANGED
@@ -1,178 +1,1 @@
1
- クラス化してしまい、フォーマットが多少異なると思いますが
2
- データ自体を辞書で管理すると各種応用が効きやすくなると思います。
3
-
4
- ```python
5
- import os
6
- import csv
7
- import pandas as pd
8
- import tkinter as tk
9
- from tkinter import messagebox
10
- from tkinter import filedialog
11
-
12
- class MainWindow(tk.Frame):
13
- def __init__(self, master):
14
- super().__init__(master)
15
- self.master.title('Hello, World!')
16
- self.master.geometry('650x300')
17
-
18
- # 各種事前定義
19
- self.data_dic = {'No': ['1','2','3','4','5','6','7','8','9','10','11'],
20
- '姓': ['渡邊','柳川','清野','根本','阿部','稲田','木内','三宅','石村','本郷','山田'],
21
- '名': ['沙樹','和臣','菜緒','駿斗','亜依','和徳','喜雄','美南','比呂','香帆','比呂'],
22
- '性別': ['女','男','女','男','女','男','男','女','男','女','男'],
23
- '生年月日': ['1988/07/15','1966/09/04','1979/06/08','1992/03/14','1977/04/04',
24
- '1963/11/06','1972/08/21','1992/11/30','1967/12/07','1965/03/20','1977/04/04']
25
- }
26
- self.colum = 3
27
- self.title = [key for key in self.data_dic.keys()]
28
- self.tx_data = [list() for i in range(len(self.title))]
29
- self.InsertAndRemoveStatus = []
30
- self.pageid = 0
31
-
32
- # 各種ウィジェット生成
33
- self.CreateWidget()
34
-
35
- ##### メインとなるウィジェットの生成
36
- def CreateWidget(self):
37
- ##############################
38
- # Label及びEntryの生成
39
- y = 50
40
- x = 140
41
- for i in self.title:
42
- tk.Label(self.master, text=i).place(x=x, y=y)
43
- x += 80
44
-
45
- y = 80
46
- for i in range(self.colum):
47
- x = 140
48
- for e, box in enumerate(self.tx_data):
49
- width = 10
50
- if e == 4:
51
- width = 14
52
- obj = tk.Entry(self.master, width=width)
53
- obj.place(x=x, y=y)
54
- box.append(obj)
55
- x += 80
56
- y += 31
57
-
58
- ##############################
59
- # 辞書データをEntryに挿入していく
60
- for (key, value), box in zip(self.data_dic.items(), self.tx_data):
61
- for data, widget in zip(value, box):
62
- widget.insert(tk.END, data)
63
-
64
- ##############################
65
- # Button関連の生成
66
- self.var = tk.BooleanVar()
67
- tk.Checkbutton(variable=self.var, text="挿入 / 削除",command =self.LabelChange).place(x=40, y=50)
68
-
69
- x = 50
70
- y = 78
71
- for i in range(self.colum):
72
- obj = tk.Button(self.master, width=10, text='挿入')
73
- obj.place(x=x, y=y)
74
- self.InsertAndRemoveStatus.append(obj)
75
- y += 30
76
-
77
- button_data = {'クリア':[25, self.FieldClear], '読込':[130, self.DataRead], '保存': [200, self.DataSave],
78
- '前ボタン': [330, self.PreviousPage], '次ボタン':[400, self.NextPage]}
79
- for key, value in button_data.items():
80
- tk.Button(self.master, text=key, command=value[1]).place(width=50, x=value[0], y=250)
81
-
82
- ##### Button Event
83
- def LabelChange(self):
84
- # 同じtextvariableを使用している為、ループする必要はなく1度の更新で全てに反映できる
85
- if self.var.get():
86
- [label.configure(text='削除') for label in self.InsertAndRemoveStatus]
87
- else:
88
- [label.configure(text='挿入') for label in self.InsertAndRemoveStatus]
89
-
90
- def NextPage(self):
91
- self.TemporaryMemory()
92
- self.FieldClear()
93
- self.pageid += 1
94
- self.EntryLoading()
95
-
96
- def PreviousPage(self):
97
- # 真偽値を測ってページidが0ならば処理を中断+エラーメッセージ
98
- if self.pageid == 0:
99
- messagebox.showerror('エラー', 'これ以上は前に戻れません')
100
- return
101
-
102
- self.TemporaryMemory()
103
- self.FieldClear()
104
- self.pageid -= 1
105
- self.EntryLoading()
106
-
107
- def EntryLoading(self):
108
- for (key, value), box in zip(self.data_dic.items(), self.tx_data):
109
- for widget, data in zip(box, value[self.pageid*self.colum: self.pageid*self.colum+self.colum]):
110
- widget.insert(tk.END, data)
111
-
112
- def DataRead(self):
113
- fTyp = [('', '.csv')]
114
- iDir = os.path.abspath(os.path.dirname(__file__))
115
- file_name = filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)
116
-
117
- # 真偽値を測りTrueの場合に読み込み処理、self.data_dicの内容を書き換える
118
- # pageidもリセットする
119
- if file_name:
120
- self.pageid = 0
121
- df = pd.read_csv(file_name, encoding='shift_jis', header=None)
122
- self.FieldClear()
123
- for i in df:
124
- dic = {}
125
- tmp = []
126
- for e, data in enumerate(df[i]):
127
- if e == 0:
128
- header = data
129
- else:
130
- tmp.append(data)
131
- self.data_dic[header] = tmp
132
-
133
- for (key, value), box in zip(self.data_dic.items(), self.tx_data):
134
- for data, widget in zip(value, box):
135
- widget.insert(tk.END, data)
136
-
137
- def DataSave(self):
138
- fTyp = [('', '.csv')]
139
- iDir = os.path.abspath(os.path.dirname(__file__))
140
- file_name = filedialog.asksaveasfilename(filetypes=fTyp, initialdir=iDir)
141
-
142
- # 保存時拡張子が入力されていない場合に拡張子を補完
1
+ `正常動作していない部分があった為修正中`
143
- if '.csv' not in file_name:
144
- file_name = file_name + '.csv'
145
- # 真偽値を測り、Trueの場合に書き込み処理、csv.writerを使用しlinetarminatorで行末を改行指定
146
- if file_name:
147
- with open(file_name, mode='w') as csvfile:
148
- writer = csv.writer(csvfile, lineterminator='\n')
149
- writer.writerow([key for key in self.data_dic.keys()])
150
- for index in range(len(self.data_dic['No'])):
151
- word = []
152
- for values in self.data_dic.values():
153
- word.append(values[index])
154
- writer.writerow(word)
155
- messagebox.showinfo('書き込み完了', f'{file_name}に保存しました')
156
-
157
- def FieldClear(self):
158
- # Entryウィジェット内の入力された文字列を全て消去
159
- for box in self.tx_data:
160
- for data in box:
161
- data.delete(0, tk.END)
162
-
163
- def TemporaryMemory(self):
164
- keys = [key for key in self.data_dic.keys()]
165
- for e, box in enumerate(self.tx_data):
166
- for n, widget in enumerate(box):
167
- data = widget.get()
168
- try:
169
- self.data_dic[keys[e]][n+self.pageid*self.colum] = data
170
- except:
171
- pass
172
-
173
-
174
- if __name__ == '__main__':
175
- root = tk.Tk()
176
- window = MainWindow(master = root)
177
- window.mainloop()
178
- ```