質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1481閲覧

[Python初心者] Tkinter Class グループ化したい。

退会済みユーザー

退会済みユーザー

総合スコア0

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/09/14 05:46

Frameで分けているコードをclassでわかりやすくしたいです。

Python

1 2import tkinter as tk 3 4 5#=-=-=-GUI-=-=-= 6#Create Instance 7win = tk.Tk() 8win.title("IVT Transcode app") 9 10win.geometry("700x700") #Turn on for locked Resolution 11win.configure(background='#52514F') # DARK MODE! | ダークモード! 12icon_photo = tk.PhotoImage(file = '/Volumes/UNSUNG HERO/PYTHON/IVTC_tool/film.png') # icon file | アイコンファイル 13win.iconphoto(False, icon_photo) # Sets the icon | アイコン 14#AppTitle = tk.Label(win, text="TDBT GUI v0.1", fg="white", bg="#52514F", font=('Verdana', 20, 'bold')) 15 16#----Frames | 枠組---- 17FrameOne = tk.LabelFrame(win, text="Input Settings", fg="white", bg="#52514F", padx="5", pady="5") #Input Settings Frame 18FrameTwo = tk.LabelFrame(win, text="Output Settings", fg="white", bg="#52514F", padx="5", pady="5") #Output Settings Frame 19FrameThree = tk.LabelFrame(win, text="Button", fg="white", bg="#52514F", pady="5", padx="5") #Buttoun Settings Frame 20FrameFour = tk.LabelFrame(win, text="Progress", fg="white", bg="#52514F", padx="5", pady="5") #Progress Settings Frame 21FrameFive = tk.LabelFrame(win, text="Preview", fg="white", bg="#52514F", padx="5", pady="5") #Preview Window Settings Frame 22 23 24#--Widgets | 特徴---- 25#Input Widgets | 入力 26Text_Input_Path = tk.Label(FrameOne, text="Input Path ", fg="white", bg="#52514F", font=('Helvetica', 10)) 27Field_Input_Path = tk.Entry(FrameOne, fg="black", highlightbackground="#52514F") 28Button_Input_Path = tk.Button(FrameOne, text="Open File", highlightbackground="#52514F", font=('Helvetica', 10)) 29 30#Output Widgets | 出力 31Text_Output_Path = tk.Label(FrameTwo, text="Output Path", fg="white", bg="#52514F", font=('Helvetica', 10)) 32Text_Output_Name = tk.Label(FrameTwo, text="Output Filename", fg="white", bg="#52514F", font=('Helvetica', 10)) 33Field_Output_Path = tk.Entry(FrameTwo, fg="black", highlightbackground="#52514F") 34Field_Output_Name = tk.Entry(FrameTwo, fg="black", highlightbackground="#52514F") 35Button_Output_Path = tk.Button(FrameTwo, text="Select Path", highlightbackground="#52514F", pady='2', font=('Helvetica', 10)) 36Extension_Value = tk.StringVar() 37Extension_Value.set(".MOV") #' default value as MOV | デフォルトMOV 38#Extension_Option = tk.OptionMenu(FrameTwo, Extension_Value) 39#Extension_Option.config(bg='#52514F', font=('Helvetica', 10), pady='2') 40 41 42#Cavas Area | キャンバスエリア 43canvas = tk.Canvas(FrameFive, width = 320, height = 240)#Canvasの作成 44canvas.create_rectangle(0, 0, 320, 240, fill = 'gray')#塗りつぶし 45canvas.place(x=0, y=0)#Canvasの配置 46 47 48#---- Button and Text | ボタンとテキスト----- 49## Button Frame ## 50ButtonOne = tk.Button(FrameThree,text="Previwe", highlightbackground="#52514F", padx=5, pady=5) #Preview 51ButtonTwo = tk.Button(FrameThree, text="Clear", highlightbackground="#52514F", padx=5, pady=5) #Clear 52Button_ffm_simple = tk.Button(FrameThree, text="Simple Transcode", highlightbackground="#52514F", padx=5, pady=5) #Simple Transcode 53 54#Preview Widgets | プレビュー 55Preview_Start = tk.Button(FrameFive, text="Start", fg="black", bg="#52514F", font=('Helvetica', 10)) 56Preview_ad1f = tk.Button(FrameFive, text=" < ", fg="black", bg="#52514F", font=('Helvetica', 10)) 57Preview_bc1f = tk.Button(FrameFive, text=" > ", fg="black", bg="#52514F", font=('Helvetica', 10)) 58MediaInfoOut = tk.Text(FrameFive, height=15, width=40, bg="white", highlightbackground='grey') 59 60## Progress Frame ## 61TextOutputText = tk.Text(FrameFour, height=3, width=80, bg="grey", highlightbackground='grey') 62ClearButton = tk.Button(FrameFour, text="Clear", highlightbackground="#52514F", padx=5, pady=5) 63 64 65#----Grid | 設計---- 66#AppTitle.grid(column=2, row=0, columnspan=4, pady="5",sticky='nsew') 67 68#Frames | 枠組 69FrameOne.grid(column=2, row=2, padx='20', pady='10', sticky='nsew') 70FrameTwo.grid(column=2, row=3, padx='20', pady='10', sticky='nsew') 71FrameThree.grid(column=3, row=2, rowspan=2, padx='20', pady='10', sticky='nsew') 72FrameFour.grid(column=2, columnspan=2, row=4, padx='20', pady='10', sticky='nsew') 73FrameFive.grid(column=2, columnspan=2, row=1, padx='20', pady='10', sticky='nsew') 74 75#Input | 入力 76Text_Input_Path.grid(column=0, row=0, sticky='w') 77Field_Input_Path.grid(column=1, row=0, sticky='nsew') 78Button_Input_Path.grid(column=2, row=0, sticky='e') 79 80#Output | 出力 81Text_Output_Path.grid(column=0, row=0, sticky='w') 82Field_Output_Path.grid(column=1, row=0, sticky='nsew') 83Button_Output_Path.grid(column=2, row=0, sticky='nsew') 84Text_Output_Name.grid(column=0, row=1, sticky='w') 85Field_Output_Name.grid(column=1, row=1, sticky='nsew') 86#Extension_Option.grid(column=2, row=1, sticky='nsew') 87 88#Preview Grid| プレビュー 89Preview_Start.grid(column=1, row=5, sticky='nsew', pady=5, padx=5) 90Preview_ad1f.grid(column=0, row=5, sticky='e', pady=5, padx=5) 91Preview_bc1f.grid(column=2, row=5, sticky='w', pady=5, padx=5) 92canvas.grid(column=0, columnspan=3, row=0, rowspan=4, pady=5, padx=5) 93MediaInfoOut.grid(column=3, row=0, rowspan=3, sticky='nw', pady=10, padx=10) 94 95#Buttons Grid | ボタンの設計 96ButtonOne.grid(column=2, row=0, sticky='nw', pady=5, padx=1) 97ButtonTwo.grid(column=2, row=1, sticky='nw', pady=5, padx=1) 98Button_ffm_simple.grid(column=2, row=2, sticky='nw', pady=5, padx=1) 99 100#Progress Grid | 進捗ウィンドウの設定 101TextOutputText.grid(column=1, columnspan=2, row=1, sticky='nsew', pady=5, padx=5) 102ClearButton.grid(column=2, row=2, sticky='e', pady=1, padx=1) 103 104 105#Start the GUI | GUI開始 106win.mainloop() 107

Applicationのメイン画面
Input_Settings
Output_Settings
Button(Controller)
Progress
Preview

上記の6つからなるフレームをClassで分けてわかりやすくしたいのですが、Classを複数持つ場合の書き方がわかりません。
どなたかご教授いただけないでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下の様なフォーマットでクラス化して書いていきます。

python

1import tkinter as tk 2 3class MyButton(tk.Button): 4 def __init__(self, master, **kwargs): 5 tk.Button.__init__(self, master, **kwargs) 6 self.configure(fg="red", font=('Helvetica', 10), command=self.button_event) 7 8 def button_event(self): 9 print('hello') 10 11win = tk.Tk() 12win.title("IVT Transcode app") 13win.geometry("700x700") 14win.configure(background='#52514F') 15 16button_1 = MyButton(win, text='classButton') 17button_1.grid(row=0, column=0, padx=20, pady=50) 18 19win.mainloop()

また、クラス化とは違いますがスッキリさせたいという事であれば
ウィジェット自体をリストに格納し、for文で設定と配置していくといった手法もあります。
個人的にこのやり方はスッキリして好きです。

python

1# row, column, columnspan, padx, pady, stickyの順 2# (rowspan,columnspanのデフォルト値は1の為、指定なしの場合は1を指定) 3Frame_info = {'Input Settings':[2, 2, 1, 1, 20, 10, 'nsew'], 4 'Output Settings':[3, 2, 1, 1, 20, 10, 'nsew'], 5 'Button':[2, 3, 2, 1, 20, 10, 'nsew'], 6 'Progress':[4, 2, 1, 2, 20, 10, 'nsew'], 7 'Preview':[1, 2, 1, 2, 20, 10, 'nsew']} 8Frames = [] 9for fname, info in Frame_info.items(): 10 tmp = tk.LabelFrame(win, text=fname, fg='white', bg='#52514F', padx=5, pady=5) 11 tmp.grid(row=info[0], column=info[1], rowspan=info[2], columnspan=info[3], padx=info[4], pady=info[5], sticky=info[6]) 12 Frames.append(tmp) 13

追記①

先程の回答とほぼ同じで、Buttonをクラス化するのかLabelFrameをクラス化するのかの違いだけで
class化しても今回のケースの場合、あまりこれ以上は綺麗に見える気もしません。

python

1class CreateFrameOne(tk.LabelFrame): 2 def __init__(self, master, **kwargs): 3 tk.LabelFrame.__init__(self, master, **kwargs) 4 self.widget_create() 5 6 def widget_create(self): 7 self.Text_Input_Path = tk.Label(self, text="Input Path ", fg="white", bg="#52514F", font=('Helvetica', 10)) 8 self.Field_Input_Path = tk.Entry(self, fg="black", highlightbackground="#52514F") 9 self.Button_Input_Path = tk.Button(self, text="Open File", highlightbackground="#52514F", font=('Helvetica', 10)) 10 11 self.Text_Input_Path.grid(column=0, row=0, sticky='w') 12 self.Field_Input_Path.grid(column=1, row=0, sticky='nsew') 13 self.Button_Input_Path.grid(column=2, row=0, sticky='e') 14 15class CreateFrameTwo(tk.LabelFrame): 16 def __init__(self, master, **kwargs): 17 tk.LabelFrame.__init__(self, master, **kwargs) 18 self.widget_create() 19 20 def widget_create(self): 21 self.Text_Output_Path = tk.Label(self, text="Output Path", fg="white", bg="#52514F", font=('Helvetica', 10)) 22 self.Text_Output_Name = tk.Label(self, text="Output Filename", fg="white", bg="#52514F", font=('Helvetica', 10)) 23 self.Field_Output_Path = tk.Entry(self, fg="black", highlightbackground="#52514F") 24 self.Field_Output_Name = tk.Entry(self, fg="black", highlightbackground="#52514F") 25 self.Button_Output_Path = tk.Button(self, text="Select Path", highlightbackground="#52514F", pady='2', font=('Helvetica', 10)) 26 self.Extension_Value = tk.StringVar() 27 self.Extension_Value.set(".MOV") 28 29 self.Text_Output_Path.grid(column=0, row=0, sticky='w') 30 self.Field_Output_Path.grid(column=1, row=0, sticky='nsew') 31 self.Button_Output_Path.grid(column=2, row=0, sticky='nsew') 32 self.Text_Output_Name.grid(column=0, row=1, sticky='w') 33 self.Field_Output_Name.grid(column=1, row=1, sticky='nsew') 34 35FrameOne = CreateFrameOne(win, text="Input Settings", fg="white", bg="#52514F") 36FrameTwo = CreateFrameOne(win, text="Input Settings", fg="white", bg="#52514F") 37FrameOne.grid(column=2, row=2, padx='20', pady='10', sticky='nsew') 38FrameTwo.grid(column=2, row=3, padx='20', pady='10', sticky='nsew')

それよりかは、目的がスッキリ見やすくさせたいといった場合に関しては
「ウィジェットの生成→定義→配置」と同じ動作を何度も繰り返すものであり
それならば、逆に考えれば同じ動作を繰り返せるという事ならばfor文を使用して簡略化できるという考えでした。

python

1# for文を使用しない場合 2FrameOne = tk.LabelFrame(win, text="Input Settings", fg="white", bg="#52514F", padx="5", pady="5") #Input Settings Frame 3FrameTwo = tk.LabelFrame(win, text="Output Settings", fg="white", bg="#52514F", padx="5", pady="5") #Output Settings Frame 4FrameThree = tk.LabelFrame(win, text="Button", fg="white", bg="#52514F", pady="5", padx="5") #Buttoun Settings Frame 5FrameFour = tk.LabelFrame(win, text="Progress", fg="white", bg="#52514F", padx="5", pady="5") #Progress Settings Frame 6FrameFive = tk.LabelFrame(win, text="Preview", fg="white", bg="#52514F", padx="5", pady="5") #Preview Window Settings Frame 7 8FrameOne.grid(column=2, row=2, padx='20', pady='10', sticky='nsew') 9FrameTwo.grid(column=2, row=3, padx='20', pady='10', sticky='nsew') 10FrameThree.grid(column=3, row=2, rowspan=2, padx='20', pady='10', sticky='nsew') 11FrameFour.grid(column=2, columnspan=2, row=4, padx='20', pady='10', sticky='nsew') 12FrameFive.grid(column=2, columnspan=2, row=1, padx='20', pady='10', sticky='nsew') 13 14# for文を使用した場合 15Frame_info = {'Input Settings':[2, 2, 1, 1, 20, 10, 'nsew'], 16 'Output Settings':[3, 2, 1, 1, 20, 10, 'nsew'], 17 'Button':[2, 3, 2, 1, 20, 10, 'nsew'], 18 'Progress':[4, 2, 1, 2, 20, 10, 'nsew'], 19 'Preview':[1, 2, 1, 2, 20, 10, 'nsew']} 20Frames = [] 21for fname, info in Frame_info.items(): 22 tmp = tk.LabelFrame(win, text=fname, fg='white', bg=main_bg, padx=5, pady=5) 23 tmp.grid(row=info[0], column=info[1], rowspan=info[2], columnspan=info[3], padx=info[4], pady=info[5], sticky=info[6]) 24 Frames.append(tmp)

また「簡読化したい」というだけの目的であればという事を前提にfor文をおすすめしておりましたが
何も必ずしもfor文を使うべきであるというものでもなく、また「どうしてもclass化がしたいんだ」という事であれば完全にお門違いな回答を差し上げてしまっておりますのでその場合には申し訳御座いません。
その場合には①のコードをご参考下さい。
いずれも見やすいか見やすくないかについては、ご自身が使用するだけのものであるか他者にもコードを共有するのかで変わってくるものである為ご自身にあった方法でコーディングしていく事をおすすめします。

投稿2020/09/14 07:37

編集2020/09/14 12:06
nto

総合スコア1438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/14 08:20

ClassごとにInput_SettingsやButtonなどを設定し、1つの塊でFrameを管理することはできないのでしょうか?
nto

2020/09/14 09:05 編集

回答を差し上げておりますが、あくまでも「フォーマット」であり 回答例ではtk.Buttonをクラスに継承していますが、tk.LabelFrameを継承したいのであればご自身でそれぞれのtk.LabelFrameを継承する様にクラス名や引数を変えてコーディングしていけば良いと思います。 が、そもそも掲題のコードではコメントアウトで綺麗にパーツ毎に既に分けられており 見栄えや整理の観点ではクラス化してもあまりやっている事は変わらずその点においてのメリットというのはあまりない様に思えます。 その為コードの簡略化を図れる様にとfor文による配置を紹介させていただきました。
退会済みユーザー

退会済みユーザー

2020/09/14 10:52

ありがとうございます。 まだまだ仕組みがわかっておらず、試行錯誤しながら行なっており応用するのに時間が掛かってしまうため、回答していただいたのに申し訳ございません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問