Passed
Push — master ( acaf9b...fbbf97 )
by Yoshihiro
44s queued 10s
created

CW   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 463
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 315
dl 0
loc 463
rs 10
c 0
b 0
f 0
wmc 6

6 Methods

Rating   Name   Duplication   Size   Complexity  
A CreateWindowClass.__init__() 0 8 1
A CreateWindowClass.frame_image() 0 40 1
A CustomText.__init__() 0 22 1
A CreateWindowClass.frame() 0 37 1
B CreateWindowClass.create_widgets() 0 197 1
B CreateWindowClass.frame_character() 0 118 1
1
import tkinter as tk
2
import tkinter.ttk as ttk
3
4
5
class CustomText(tk.Text):
6
    """Textのイベントを拡張したウィジェット
7
8
    ・textに<<Scroll>>イベントと、<<Change>>イベントを追加する。
9
10
    """
11
    def __init__(self, master, **kwargs):
12
        super().__init__(master, **kwargs)
13
        self.tk.eval('''
14
            proc widget_proxy {widget widget_command args} {
15
                set result [uplevel [linsert $args 0 $widget_command]]
16
                if {([lrange $args 0 1] == {xview moveto}) ||
17
                    ([lrange $args 0 1] == {xview scroll}) ||
18
                    ([lrange $args 0 1] == {yview moveto}) ||
19
                    ([lrange $args 0 1] == {yview scroll})} {
20
                    event generate  $widget <<Scroll>> -when tail
21
                }
22
                if {([lindex $args 0] in {insert replace delete})} {
23
                    event generate  $widget <<Change>> -when tail
24
                }
25
                # return the result from the real widget command
26
                return $result
27
            }
28
            ''')
29
        self.tk.eval('''
30
            rename {widget} _{widget}
31
            interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}
32
        '''.format(widget=str(self)))
33
34
35
class CreateWindowClass():
36
    """画面の描画のクラス
37
38
    ・画面描画にあるプログラム群
39
40
    """
41
    def __init__(self, app):
42
        """
43
        Args:
44
            app (instance): lineframeインスタンス
45
46
        """
47
        self.APP = app
48
        self.BLANK_IMAGE = '''R0lGODlhHgAeAPcAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz
49
            /wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDM
50
            mQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMz
51
            MzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ
52
            /zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYA
53
            mWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZ
54
            M2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb/
55
            /5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplm
56
            mZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/
57
            M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz
58
            /8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszM
59
            mczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8z
60
            M/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z
61
            ///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///8DAwICAgIAAAACA
62
            AAAAgICAAIAAgACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
63
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
64
            AAAAAAAAAAAAAAAAACwAAAAAHgAeAAAIMgABCBxIsKDBgwgTKlzIsKHDhxAjSpxI
65
            saLFixgzatzIsaPHjyBDihxJsqTJkyhTngwIADs=
66
            '''
67
68
    def create_widgets(self):
69
        """画面の描画
70
71
        ・メインウインドウにウェジットを配置する。
72
73
        """
74
        # メニューの配置
75
        File_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
76
        Edit_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
77
        List_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
78
        Processing_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
79
        Help_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
80
        # ファイルメニュー
81
        File_menu.add_command(
82
            label=u'新規作成(N)',
83
            under=5,
84
            accelerator='Ctrl+N',
85
            command=self.APP.fmc.new_open
86
        )
87
        File_menu.add_command(
88
            label=u'開く(O)',
89
            under=3,
90
            accelerator='Ctrl+E',
91
            command=self.APP.fmc.open_file
92
        )
93
        File_menu.add_separator()
94
        File_menu.add_command(
95
            label=u'保存(S)',
96
            under=3,
97
            accelerator='Ctrl+S',
98
            command=self.APP.fmc.overwrite_save_file
99
        )
100
        File_menu.add_command(
101
            label=u'名前を付けて保存(W)',
102
            under=9,
103
            accelerator='Ctrl+W',
104
            command=self.APP.fmc.save_file
105
        )
106
        File_menu.add_separator()
107
        File_menu.add_command(
108
            label=u'閉じる(C)',
109
            under=4,
110
            accelerator='Ctrl+C',
111
            command=self.APP.fmc.on_closing
112
        )
113
        self.APP.menu_bar.add_cascade(
114
            label=u'ファイル(F)',
115
            under=5,
116
            menu=File_menu
117
        )
118
        # 編集メニュー
119
        Edit_menu.add_command(
120
            label=u'やり直し(R)',
121
            under=5,
122
            accelerator='Ctrl+Shift+Z',
123
            command=self.APP.emc.redo
124
        )
125
        Edit_menu.add_command(
126
            label=u'戻る(U)',
127
            under=3,
128
            accelerator='Ctrl+Z',
129
            command=self.APP.emc.undo
130
        )
131
        Edit_menu.add_separator()
132
        Edit_menu.add_command(
133
            label=u'切り取り(X)',
134
            under=5,
135
            accelerator='Ctrl+X',
136
            command=self.APP.emc.cut
137
        )
138
        Edit_menu.add_command(
139
            label=u'コピー(C)',
140
            under=4,
141
            accelerator='Ctrl+C',
142
            command=self.APP.emc.copy
143
        )
144
        Edit_menu.add_command(
145
            label=u'貼り付け(V)',
146
            under=5,
147
            accelerator='Ctrl+V',
148
            command=self.APP.emc.paste
149
        )
150
        Edit_menu.add_separator()
151
        Edit_menu.add_command(
152
            label=u'検索(F)',
153
            under=3,
154
            accelerator='Ctrl+F',
155
            command=self.APP.fpc.find_dialog
156
        )
157
        Edit_menu.add_command(
158
            label=u'置換(L)',
159
            under=3,
160
            accelerator='Ctrl+L',
161
            command=self.APP.fpc.replacement_dialog
162
        )
163
        self.APP.menu_bar.add_cascade(
164
            label=u'編集(E)',
165
            under=3,
166
            menu=Edit_menu
167
        )
168
        # 処理メニュー
169
        Processing_menu.add_command(
170
            label=u'ルビをふる(R)',
171
            under=6,
172
            accelerator='Ctrl+R',
173
            command=self.APP.pmc.ruby_huri
174
        )
175
        Processing_menu.add_command(
176
            label=u'文字数のカウント(C)',
177
            under=9,
178
            accelerator='Ctrl+Shift+C',
179
            command=self.APP.pmc.count_moji
180
        )
181
        Processing_menu.add_command(
182
            label=u'選択文字の意味(M)',
183
            under=8,
184
            accelerator='Ctrl+Shift+F',
185
            command=self.APP.pmc.find_wikipedia
186
        )
187
        Processing_menu.add_command(
188
            label=u'文章の読み上げ(B)',
189
            under=8,
190
            accelerator='Ctrl+Shift+R',
191
            command=self.APP.pmc.read_text
192
        )
193
        Processing_menu.add_command(
194
            label=u'文章校正(Y)',
195
            under=5,
196
            accelerator='Ctrl+Y',
197
            command=self.APP.pmc.yahoo
198
        )
199
        Processing_menu.add_separator()
200
        Processing_menu.add_command(
201
            label=u'フォントサイズの変更(F)',
202
            under=11,
203
            accelerator='Ctrl+Shift+F',
204
            command=self.APP.pmc.font_dialog
205
        )
206
        Processing_menu.add_separator()
207
        Processing_menu.add_command(
208
            label=u'「小説家になろう」のページを開く(U)',
209
            under=17,
210
            accelerator='Ctrl+U',
211
            command=self.APP.pmc.open_becoming_novelist_page
212
        )
213
        self.APP.menu_bar.add_cascade(
214
            label=u'処理(P)',
215
            under=3,
216
            menu=Processing_menu
217
        )
218
        # リストメニュー
219
        List_menu.add_command(
220
            label=u'項目を増やす(U)',
221
            under=7,
222
            accelerator='選択右クリック',
223
            command=self.APP.lmc.message_window
224
        )
225
        List_menu.add_command(
226
            label=u'項目を削除(D)',
227
            under=6,
228
            accelerator='選択右クリック',
229
            command=self.APP.lmc.message_window
230
        )
231
        List_menu.add_command(
232
            label=u'項目の名前を変更(C)',
233
            under=9,
234
            accelerator='Ctrl+G',
235
            command=self.APP.lmc.on_name_click
236
        )
237
        self.APP.menu_bar.add_cascade(
238
            label=u'リスト(L)',
239
            under=4,
240
            menu=List_menu
241
        )
242
        # ヘルプメニュー
243
        Help_menu.add_command(
244
            label=u'ヘルプ(H)',
245
            under=4,
246
            accelerator='Ctrl+H',
247
            command=self.APP.hmc.help
248
        )
249
        Help_menu.add_command(
250
            label=u'バージョン情報(V)',
251
            under=8,
252
            accelerator='Ctrl+Shift+V',
253
            command=self.APP.hmc.version
254
        )
255
        self.APP.menu_bar.add_cascade(
256
            label=u'ヘルプ(H)',
257
            under=4,
258
            menu=Help_menu
259
        )
260
        # ツリーコントロール、入力欄、行番号欄、スクロール部分を作成
261
        self.APP.tree = ttk.Treeview(self.APP, show="tree")
262
        self.APP.tree.grid(row=0, column=0, sticky=(tk.N, tk.S))
263
        self.frame()
264
        self.APP.fmc.tree_get_loop()
265
266
    def frame(self):
267
        """フレーム内にテキストボックスを表示
268
269
        ・メインウインドウの右側に行番号、テキストボックス、スクロールバー
270
        を表示する。
271
272
        """
273
        # f1フレームにテキストエディタを表示
274
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
275
        self.APP.text = CustomText(
276
            self.APP.f1,
277
            font=(self.APP.font, self.APP.pmc.font_size),
278
            undo=True
279
        )
280
        self.APP.line_numbers = tk.Canvas(self.APP.f1, width=30)
281
        self.APP.ysb = ttk.Scrollbar(
282
            self.APP.f1,
283
            orient=tk.VERTICAL,
284
            command=self.APP.text.yview
285
        )
286
        # 入力欄にスクロールを紐付け
287
        self.APP.text.configure(yscrollcommand=self.APP.ysb.set)
288
        # 左から行番号、入力欄、スクロールウィジェット
289
        self.APP.line_numbers.grid(row=0, column=0, sticky=(tk.N, tk.S))
290
        self.APP.text.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
291
        self.APP.ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
292
        self.APP.f1.columnconfigure(1, weight=1)
293
        self.APP.f1.rowconfigure(0, weight=1)
294
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
295
        # テキスト入力欄のみ拡大されるように
296
        self.APP.columnconfigure(1, weight=1)
297
        self.APP.rowconfigure(0, weight=1)
298
        # テキストを読み取り専用にする
299
        self.APP.text.configure(state='disabled')
300
        # テキストにフォーカスを当てる
301
        self.APP.text.focus()
302
        self.APP.epc.create_event_text()
303
304
    def frame_image(self):
305
        """フレーム内にイメージフレーム表示
306
307
        ・メインウインドウの右側にイメージキャンバス、スクロールバーを表示する。
308
309
        """
310
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
311
        self.APP.image_space = tk.Canvas(self.APP.f1, bg="black", width=30)
312
        self.APP.image_ysb = ttk.Scrollbar(
313
            self.APP.f1,
314
            orient=tk.VERTICAL,
315
            command=self.APP.image_space.yview
316
        )
317
        self.APP.image_xsb = ttk.Scrollbar(
318
            self.APP.f1,
319
            orient=tk.HORIZONTAL,
320
            command=self.APP.image_space.xview
321
        )
322
        self.APP.image_space.configure(xscrollcommand=self.APP.image_xsb.set)
323
        self.APP.image_space.configure(yscrollcommand=self.APP.image_ysb.set)
324
        self.APP.image_space.grid(
325
            row=0,
326
            column=1,
327
            sticky=(tk.N, tk.S, tk.W, tk.E)
328
        )
329
        self.APP.image_ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
330
        self.APP.image_xsb.grid(row=1, column=1, sticky=(tk.W, tk.E))
331
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
332
        self.APP.f1.columnconfigure(1, weight=1)
333
        self.APP.f1.rowconfigure(0, weight=1)
334
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
335
        # デフォルトの画像を設定する
336
        self.APP.image_space.photo = tk.PhotoImage(data=self.BLANK_IMAGE)
337
        self.APP.image_on_space = self.APP.image_space.create_image(
338
            0,
339
            0,
340
            anchor='nw',
341
            image=self.APP.image_space.photo
342
        )
343
        self.APP.epc.create_event_image()
344
345
    def frame_character(self):
346
        """フレーム内にイメージフレーム表示
347
348
        ・メインウインドウの右側に呼び名、似顔絵、名前、誕生日、略歴を表示する。
349
350
        """
351
        # チェック有無変数
352
        self.APP.var = tk.IntVar()
353
        # value=0のラジオボタンにチェックを入れる
354
        self.APP.var.set(0)
355
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
356
        self.APP.label1 = tk.Label(self.APP.f1, text=u"呼び名")
357
        self.APP.txt_yobi_name = ttk.Entry(
358
            self.APP.f1, width=30,
359
            font=(self.APP.font, self.APP.pmc.font_size)
360
        )
361
        self.APP.label2 = tk.Label(self.APP.f1, text=u"名前")
362
        self.APP.txt_name = ttk.Entry(
363
            self.APP.f1, width=40,
364
            font=(self.APP.font, self.APP.pmc.font_size)
365
        )
366
        self.APP.f2 = tk.LabelFrame(
367
            self.APP.f1,
368
            relief=tk.RIDGE,
369
            bd=2,
370
            text=u"性別"
371
        )
372
        self.APP.rdo1 = tk.Radiobutton(
373
            self.APP.f2, value=0,
374
            variable=self.APP.var,
375
            text=u'男'
376
        )
377
        self.APP.rdo2 = tk.Radiobutton(
378
            self.APP.f2, value=1,
379
            variable=self.APP.var,
380
            text=u'女'
381
        )
382
        self.APP.rdo3 = tk.Radiobutton(
383
            self.APP.f2, value=2,
384
            variable=self.APP.var,
385
            text=u'その他'
386
        )
387
        self.APP.rdo1.grid(row=0, column=1)
388
        self.APP.rdo2.grid(row=1, column=1)
389
        self.APP.rdo3.grid(row=2, column=1)
390
        self.APP.f3 = tk.LabelFrame(
391
            self.APP.f1,
392
            relief=tk.RIDGE,
393
            bd=2,
394
            text=u"似顔絵"
395
        )
396
        self.APP.cv = self.APP.foto_canvas = tk.Canvas(
397
            self.APP.f3,
398
            bg="black",
399
            width=149,
400
            height=199
401
        )
402
        self.APP.foto_canvas.grid(row=0, column=0)
403
        self.APP.label3 = tk.Label(self.APP.f1, text=u"誕生日")
404
        self.APP.txt_birthday = ttk.Entry(
405
            self.APP.f1, width=40,
406
            font=(self.APP.font, self.APP.pmc.font_size)
407
        )
408
        self.APP.f4 = tk.Frame(self.APP.f1)
409
        self.APP.foto_button = ttk.Button(
410
            self.APP.f4,
411
            width=5,
412
            text=u'挿入',
413
            command=self.APP.sfc.btn_click
414
        )
415
        self.APP.foto_button_calcel = ttk.Button(
416
            self.APP.f4,
417
            width=5,
418
            text=u'消去',
419
            command=self.APP.sfc.clear_btn_click
420
        )
421
        self.APP.foto_button.grid(row=0, column=1)
422
        self.APP.foto_button_calcel.grid(row=1, column=1)
423
        self.APP.label4 = tk.Label(self.APP.f1, text=u"略歴")
424
        self.APP.text_body = tk.Text(
425
            self.APP.f1,
426
            width=80,
427
            font=(self.APP.font, self.APP.pmc.font_size)
428
        )
429
        self.APP.label1.grid(row=0, column=1, columnspa=2)
430
        self.APP.txt_yobi_name.grid(row=1, column=1, columnspa=2)
431
        self.APP.f2.grid(row=2, column=1, rowspan=2)
432
        self.APP.f4.grid(row=3, column=2)
433
        self.APP.f3.grid(row=0, column=3, rowspan=4)
434
        self.APP.label2.grid(row=0, column=4, sticky=(tk.N, tk.S, tk.W, tk.E))
435
        self.APP.txt_name.grid(row=1, column=4)
436
        self.APP.label3.grid(row=2, column=4)
437
        self.APP.txt_birthday.grid(row=3, column=4)
438
        self.APP.label4.grid(row=4, column=1, columnspa=4)
439
        self.APP.text_body.grid(
440
            row=5,
441
            column=1,
442
            columnspa=4,
443
            sticky=(tk.N, tk.S, tk.W, tk.E)
444
        )
445
        self.APP.f1.columnconfigure(1, weight=1)
446
        self.APP.f1.columnconfigure(4, weight=1)
447
        self.APP.f1.rowconfigure(5, weight=1)
448
449
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
450
        self.APP.columnconfigure(1, weight=1)
451
        self.APP.rowconfigure(0, weight=1)
452
        # デフォルトの画像を設定する
453
        self.APP.cv.photo = tk.PhotoImage(data=self.BLANK_IMAGE)
454
        self.APP.image_on_canvas = self.APP.cv.create_image(
455
            0,
456
            0,
457
            anchor='nw',
458
            image=self.APP.cv.photo
459
        )
460
461
        # キャラクターイベントを追加
462
        self.APP.epc.create_event_character()
463