質問編集履歴

1

コードを簡略化しました。

2019/01/15 15:19

投稿

ChaCha_MaRu
ChaCha_MaRu

スコア15

test CHANGED
File without changes
test CHANGED
@@ -4,576 +4,6 @@
4
4
 
5
5
  ```python
6
6
 
7
- # -*- coding: utf-8 -*-
8
7
 
9
8
 
10
-
11
- import tkinter as tk
12
-
13
- # python2の場合は、import Tkinter as tk
14
-
15
- import tkinter.ttk as ttk
16
-
17
- # python2の場合は、import ttk
18
-
19
- import sqlite3
20
-
21
-
22
-
23
- # 登録画面のGUI
24
-
25
- def create_gui():
26
-
27
- # ----------------------------------------
28
-
29
- # コールバック関数群
30
-
31
- # ----------------------------------------
32
-
33
- # 表示ボタンが押下されたときのコールバック関数
34
-
35
- def select_button():
36
-
37
- root.destroy()
38
-
39
- select_gui()
40
-
41
- # ----------------------------------------
42
-
43
- # 終了ボタンが押下されたときのコールバック関数
44
-
45
- def quit_button():
46
-
47
- root.destroy()
48
-
49
- # ----------------------------------------
50
-
51
- # 登録ボタンがクリックされた時にデータをDBに登録するコールバック関数
52
-
53
- def create_sql(item_name):
54
-
55
-
56
-
57
- # データベースに接続
58
-
59
- c = sqlite3.connect("database.db")
60
-
61
- # item_nameをWHERE句に渡してitem_codeを取得する
62
-
63
- item_code = c.execute("""
64
-
65
- SELECT item_code FROM item
66
-
67
- WHERE item_name = '{}'
68
-
69
- """.format(item_name))
70
-
71
- item_code = item_code.fetchone()[0]
72
-
73
- # 日付の読み取り
74
-
75
- acc_data = entry1.get().replace("/","-")
76
-
77
- # 金額の読み取り
78
-
79
- amount = entry3.get()
80
-
81
-
82
-
83
- # SQLを発行してDBへ登録
84
-
85
- # python2の場合は、ユニコード文字列でsqlite3に渡す
86
-
87
- # また、コミットする場合は、commitメソッドを用いる
88
-
89
- try:
90
-
91
- c.execute("""
92
-
93
- INSERT INTO acc_data(acc_date,item_code,amount)
94
-
95
- VALUES('{}',{},{});
96
-
97
- """.format(acc_data,item_code,amount))
98
-
99
- c.execute("COMMIT;")
100
-
101
- print("1件登録しました")
102
-
103
- # ドメインエラーなどにより登録できなかった場合のエラー処理
104
-
105
- except:
106
-
107
- print("エラーにより登録できませんでした")
108
-
109
- # ----------------------------------------
110
-
111
- # 内訳テーブル(item)にあるitem_nameのタプルを作成する
112
-
113
- def createitemname():
114
-
115
- # データベースの接続
116
-
117
- c = sqlite3.connect("database.db")
118
-
119
- # 空の「リスト型」を定義
120
-
121
- li = []
122
-
123
- # SELECT文を発行し、item_nameを取得し、for文で回す
124
-
125
- for r in c.execute("SELECT item_name FROM item"):
126
-
127
- # item_nameをリストに追加する
128
-
129
- li.append(r)
130
-
131
- # リスト型のliをタプル型に変換して、ファンクションに戻す
132
-
133
- return tuple(li)
134
-
135
- # ----------------------------------------
136
-
137
-
138
-
139
- # 空のデータベースを作成して接続する
140
-
141
- dbname = "database.db"
142
-
143
- c = sqlite3.connect(dbname)
144
-
145
- c.execute("PRAGMA foreign_keys = 1")
146
-
147
-
148
-
149
- # 既にデータベースが登録されている場合は、ddlの発行でエラーが出るのでexceptブロックで回避する
150
-
151
- try:
152
-
153
- # itemテーブルの定義
154
-
155
- ddl = """
156
-
157
- CREATE TABLE item
158
-
159
- (
160
-
161
- item_code INTEGER PRIMARY KEY AUTOINCREMENT,
162
-
163
- item_name TEXT NOT NULL UNIQUE
164
-
165
- )
166
-
167
- """
168
-
169
- # SQLの発行
170
-
171
- c.execute(ddl)
172
-
173
- # acc_dataテーブルの定義
174
-
175
- ddl = """
176
-
177
- CREATE TABLE acc_data
178
-
179
- (
180
-
181
- id INTEGER PRIMARY KEY AUTOINCREMENT,
182
-
183
- acc_date DATE NOT NULL,
184
-
185
- item_code INTEGER NOT NULL,
186
-
187
- amount INTEGER,
188
-
189
- FOREIGN KEY(item_code) REFERENCES item(item_code)
190
-
191
- )
192
-
193
- """
194
-
195
- # itemテーブルへリファレンスデータの登録
196
-
197
- c.execute(ddl)
198
-
199
- c.execute("INSERT INTO item VALUES(1,'食費')")
200
-
201
- c.execute("INSERT INTO item VALUES(2,'住宅費')")
202
-
203
- c.execute("INSERT INTO item VALUES(3,'光熱費')")
204
-
205
- c.execute("COMMIT")
206
-
207
- except:
208
-
209
- pass
210
-
211
-
212
-
213
- # rootフレームの設定
214
-
215
- root = tk.Tk()
216
-
217
- root.title("家計簿アプリ")
218
-
219
- root.geometry("300x280")
220
-
221
-
222
-
223
- # メニューの設定
224
-
225
- frame = tk.Frame(root,bd=2,relief="ridge")
226
-
227
- frame.pack(fill="x")
228
-
229
- button1 = tk.Button(frame,text="入力")
230
-
231
- button1.pack(side="left")
232
-
233
- button2 = tk.Button(frame,text="表示",command=select_button)
234
-
235
- button2.pack(side="left")
236
-
237
- button3 = tk.Button(frame,text="終了",command=quit_button)
238
-
239
- button3.pack(side="right")
240
-
241
-
242
-
243
- # 入力画面ラベルの設定
244
-
245
- label1 = tk.Label(root,text="【入力画面】",font=("",16),height=2)
246
-
247
- label1.pack(fill="x")
248
-
249
-
250
-
251
- # 日付のラベルとエントリーの設定
252
-
253
- frame1 = tk.Frame(root,pady=10)
254
-
255
- frame1.pack()
256
-
257
- label2 = tk.Label(frame1,font=("",14),text="日付")
258
-
259
- label2.pack(side="left")
260
-
261
- entry1 = tk.Entry(frame1,font=("",14),justify="center",width=15)
262
-
263
- entry1.pack(side="left")
264
-
265
-
266
-
267
- # 内訳のラベルとエントリーの設定
268
-
269
- frame2 = tk.Frame(root,pady=10)
270
-
271
- frame2.pack()
272
-
273
- label3 = tk.Label(frame2,font=("",14),text="内訳")
274
-
275
- label3.pack(side="left")
276
-
277
- # 内訳コンボボックスの作成
278
-
279
- combo = ttk.Combobox(frame2, state='readonly',font=("",14),width=13)
280
-
281
- combo["values"] = createitemname()
282
-
283
- combo.current(0)
284
-
285
- combo.pack()
286
-
287
-
288
-
289
- # 金額のラベルとエントリーの設定
290
-
291
- frame3 = tk.Frame(root,pady=10)
292
-
293
- frame3.pack()
294
-
295
- label4 = tk.Label(frame3,font=("",14),text="金額")
296
-
297
- label4.pack(side="left")
298
-
299
- entry3 = tk.Entry(frame3,font=("",14),justify="center",width=15)
300
-
301
- entry3.pack(side="left")
302
-
303
-
304
-
305
- # 登録ボタンの設定
306
-
307
- button4 = tk.Button(root,text="登録",
308
-
309
- font=("",16),
310
-
311
- width=10,bg="gray",
312
-
313
- command=lambda:create_sql(combo.get()))
314
-
315
- button4.pack()
316
-
317
-
318
-
319
- root.mainloop()
320
-
321
-
322
-
323
- # 表示画面のGUI
324
-
325
- def select_gui():
326
-
327
- # ----------------------------------------
328
-
329
- # コールバック関数群
330
-
331
- # ----------------------------------------
332
-
333
- # 登録ボタンが押下されたときのコールバック関数
334
-
335
- def create_button():
336
-
337
- root.destroy()
338
-
339
- create_gui()
340
-
341
- # ----------------------------------------
342
-
343
- # 終了ボタンが押下されたときのコールバック関数
344
-
345
- def quit_button():
346
-
347
- root.destroy()
348
-
349
- # ----------------------------------------
350
-
351
- # 表示ボタンが押下されたときのコールバック関数
352
-
353
- def select_sql(start,end):
354
-
355
- # treeviewのアイテムをすべて削除
356
-
357
- tree.delete(*tree.get_children())
358
-
359
- # 開始日と終了日が空欄だったらデフォルト値の設定
360
-
361
- if start == "":
362
-
363
- start = "1900-01-01"
364
-
365
- if end == "":
366
-
367
- end = "2100-01-01"
368
-
369
- #SELECT文の作成
370
-
371
- sql = """
372
-
373
- SELECT acc_date,item_name,amount
374
-
375
- FROM acc_data as a,item as i
376
-
377
- WHERE a.item_code = i.item_code AND
378
-
379
- acc_date BETWEEN '{}' AND '{}'
380
-
381
- ORDER BY acc_date
382
-
383
- """.format(start,end)
384
-
385
- # ツリービューにアイテムの追加
386
-
387
- i=0
388
-
389
- for r in c.execute(sql):
390
-
391
- # 金額(r[2])を通貨形式に変換
392
-
393
- r = (r[0],r[1],"¥{:,d}".format(r[2]))
394
-
395
- tree.insert("","end",tags=i,values=r)
396
-
397
- if i & 1:
398
-
399
- tree.tag_configure(i,background="#CCFFFF")
400
-
401
- i+=1
402
-
403
- # ----------------------------------------
404
-
405
-
406
-
407
- # 空のデータベースを作成して接続する
408
-
409
- dbname = "database.db"
410
-
411
- c = sqlite3.connect(dbname)
412
-
413
- c.execute("PRAGMA foreign_keys = 1")
414
-
415
-
416
-
417
- # rootフレームの設定
418
-
419
- root = tk.Tk()
420
-
421
- root.title("家計簿アプリ")
422
-
423
- root.geometry("400x500")
424
-
425
-
426
-
427
- # メニューの設定
428
-
429
- frame = tk.Frame(root,bd=2,relief="ridge")
430
-
431
- frame.pack(fill="x")
432
-
433
- button1 = tk.Button(frame,text="入力",command=create_button)
434
-
435
- button1.pack(side="left")
436
-
437
- button2 = tk.Button(frame,text="表示")
438
-
439
- button2.pack(side="left")
440
-
441
- button3 = tk.Button(frame,text="終了",command=quit_button)
442
-
443
- button3.pack(side="right")
444
-
445
-
446
-
447
- # 入力画面ラベルの設定
448
-
449
- label1 = tk.Label(root,text="【表示画面】",font=("",16),height=2)
450
-
451
- label1.pack(fill="x")
452
-
453
-
454
-
455
- # 期間選択のラベルエントリーの設定
456
-
457
- frame1 = tk.Frame(root,pady=15)
458
-
459
- frame1.pack()
460
-
461
- label2 = tk.Label(frame1,font=("",14),text="期間 ")
462
-
463
- label2.pack(side="left")
464
-
465
- entry1 = tk.Entry(frame1,font=("",14),justify="center",width=12)
466
-
467
- entry1.pack(side="left")
468
-
469
- label3 = tk.Label(frame1,font=("",14),text=" ~ ")
470
-
471
- label3.pack(side="left")
472
-
473
- entry2 = tk.Entry(frame1,font=("",14),justify="center",width=12)
474
-
475
- entry2.pack(side="left")
476
-
477
-
478
-
479
- # 表示ボタンの設定
480
-
481
- button4 = tk.Button(root,text="表示",
482
-
483
- font=("",16),
484
-
485
- width=10,bg="gray",
486
-
487
- command=lambda:select_sql(entry1.get(),entry2.get()))
488
-
489
- button4.pack()
490
-
491
-
492
-
493
- # ツリービューの作成
494
-
495
- tree = ttk.Treeview(root,padding=10)
496
-
497
- tree["columns"] = (1,2,3)
498
-
499
- tree["show"] = "headings"
500
-
501
- tree.column(1,width=100)
502
-
503
- tree.column(2,width=75)
504
-
505
- tree.column(3,width=100)
506
-
507
- tree.heading(1,text="日付")
508
-
509
- tree.heading(2,text="内訳")
510
-
511
- tree.heading(3,text="金額")
512
-
513
-
514
-
515
- # ツリービューのスタイル変更
516
-
517
- style = ttk.Style()
518
-
519
- # TreeViewの全部に対して、フォントサイズの変更
520
-
521
- style.configure("Treeview",font=("",12))
522
-
523
- # TreeViewのHeading部分に対して、フォントサイズの変更と太字の設定
524
-
525
- style.configure("Treeview.Heading",font=("",14,"bold"))
526
-
527
-
528
-
529
- # SELECT文の作成
530
-
531
- sql = """
532
-
533
- SELECT acc_date,item_name,amount
534
-
535
- FROM acc_data as a,item as i
536
-
537
- WHERE a.item_code = i.item_code
538
-
539
- ORDER BY acc_date
540
-
541
- """
542
-
543
- # ツリービューにアイテムの追加
544
-
545
- i=0
546
-
547
- for r in c.execute(sql):
548
-
549
- # 金額(r[2])を通貨形式に変換
550
-
551
- r = (r[0],r[1],"¥{:,d}".format(r[2]))
552
-
553
- tree.insert("","end",tags=i,values=r)
554
-
555
- if i & 1:
556
-
557
- tree.tag_configure(i,background="#CCFFFF")
558
-
559
- i+=1
560
-
561
- # ツリービューの配置
562
-
563
- tree.pack(fill="x",padx=20,pady=20)
564
-
565
-
566
-
567
- # メインループ
568
-
569
- root.mainloop()
570
-
571
-
572
-
573
-
574
-
575
- # GUI画面の表示
576
-
577
- create_gui()
578
-
579
9
  ```