72306


tkinterでGUI画面を作成しており、Frameによりオブジェクトを分けて実装しています。  
その一部の内部ボタンを押すと、別のFrameの表示を変更しようとしています。

下記のコードのように、呼び出し元自体をFrameオブジェクトに渡してしまえば、呼び出し元のメソッドを通じて別のFrameに変更を加えられます。

もっとスマートな書き方はないでしょうか？

[code]

    from tkinter import *
    
    class class_Main():
        def __init__(self):
            self.mode = 0
            self.root = Tk()
    
            self.iTopFrame = class_TopFrame(self,self.root)
            self.iMainFrame = class_MainFrame(self,self.root)
    
        def run(self):
            self.root.mainloop()
    
        def TopClicked(self):
            self.mode  = 1-self.mode
            self.iMainFrame.set_widget(self.mode)
    
            pass
    
    class class_TopFrame():
        def __init__(self,parent,root):
    
            _InFrame_ = Frame(root)
            self.Button = Button(_InFrame_,text='change',command=parent.TopClicked)
    
            self.Button.grid()
            _InFrame_.grid()
    
    class class_MainFrame():
        def __init__(self,parent,root):
    
            _InFrame_ = Frame(root)
            self.mode = 0
    
            self.Button1 = Button(_InFrame_,text='mode1')
            self.Button2 = Button(_InFrame_,text='mode2')
            self.Button1.grid(row=0,column=0)
            self.Button2.grid(row=0,column=0)
    
            _InFrame_.grid()
    
            self.set_widget(self.mode)
    
        def set_widget(self,mode):
            if mode == 0:
                self.Button2.grid_remove()
                self.Button1.grid()
            else:
                self.Button1.grid_remove()
                self.Button2.grid()
    
    class_Main().run()
    
[/code]


CC BY-SA 4.0
2020-11-30T07:16:10.110
72291
2020-12-01T02:14:12.510
2020-11-30T11:21:33.363
3060
32891
question
python tkinter
Tkinter でボタンが押されたときに別のオブジェクトの表示を変更したい


呼び出し元でボタンとイベントを[バインド](https://docs.python.org/ja/3/library/tkinter.html#bindings-
and-events)する方法があります。  
スマートかどうかは分かりませんが、バインドを使うことで呼び出し元がMVVMのViewModelっぽくオブジェクト間の通信を制御することができます。  
各Frame(MVVMのView)はそれぞれのFrame内部の制御のみに集中できるので、今回の例で言えば呼び出し元に`TopClicked`イベントがあるかどうかを`class_TopFrame`側が気にしなくて良くなります。

[code]

    from tkinter import *
    
    class class_Main():
        def __init__(self):
            self.mode = 0
            self.root = Tk()
    
            self.iTopFrame = class_TopFrame(self.root)
            self.iMainFrame = class_MainFrame(self.root)
            # 主な修正箇所
            self.iTopFrame.Button.bind("<Button-1>", self.TopClicked)
    
        def run(self):
            self.root.mainloop()
    
        def TopClicked(self, event):
            self.mode  = 1-self.mode
            self.iMainFrame.set_widget(self.mode)
    
            pass
    
    class class_TopFrame():
        def __init__(self,root):
    
            _InFrame_ = Frame(root)
            self.Button = Button(_InFrame_,text='change')
    
            self.Button.grid()
            _InFrame_.grid()
    
    class class_MainFrame():
        def __init__(self,root):
    
            _InFrame_ = Frame(root)
            self.mode = 0
    
            self.Button1 = Button(_InFrame_,text='mode1')
            self.Button2 = Button(_InFrame_,text='mode2')
            self.Button1.grid(row=0,column=0)
            self.Button2.grid(row=0,column=0)
    
            _InFrame_.grid()
    
            self.set_widget(self.mode)
    
        def set_widget(self,mode):
            if mode == 0:
                self.Button2.grid_remove()
                self.Button1.grid()
            else:
                self.Button1.grid_remove()
                self.Button2.grid()
    
    class_Main().run()
    
[/code]


CC BY-SA 4.0
2020-12-01T02:14:12.510
72306
2020-12-01T02:14:12.510
9820
72291
answer