Suppose I have a tkinter app with the following layout.
I have used an object-oriented hierarchical model such that the classes are instantiated like this:
MainWindow
├── OptionsFrame
│ ├── DataFrame
│ ├── MetaFrame
│ └── SaveFrame
└── PlotFrame
I want to be able to use the plot button within the SaveFrame to run a function which will plot using a FigureCanvasTkAgg canvas object.
I am struggling to see how I can reach the PlotFrame from within the SaveFrame.
So far I have been using a main
parameter in my class declarations, i.e.
class SaveFrame(ttk.Frame):
def __init__(self, main, *args, **kwargs):
super().__init__(main, *args, **kwargs)
self.main = main
which will allow me to go up one level of the hierarchy to the OptionsFrame, but what I need to do is go from
SaveFrame -> OptionsFrame -> MainWindow -> PlotFrame
I don't really know how this is possible.
Thanks
CodePudding user response:
Standard widgets get parent as first argument and keep it in self.master
- you don't need self.main
.
Using self.master
you can access parent and using self.master.master
can acess grandparent
, etc. - and this grandparent
can be your MainWindow
.
If MainWindow
keeps PlotFrame
as i.e. self.plot_frame
then SaveFrame
may needs
self.master.master.plot_frame
EDIT:
Other method is to send PlotFrame
(self.plot_frame
) as argument to OptionsFrame
and it should send it as argument to SaveFrame
and it will have direct access to PlotFrame
class SaveFrame(ttk.Frame):
def __init__(self, main, plot_frame, *args, **kwargs):
super().__init__(main, *args, **kwargs)
self.main = main
self.plot_frame = plot_frame
class OptionsFrame(ttk.Frame):
def __init__(self, main, plot_frame, *args, **kwargs):
super().__init__(main, *args, **kwargs)
self.main = main
self.save_frame = SaveFrame(main, plot_frame)
# in MainWindow
self.plot_frame = PlotFrame(...)
self.options_frame = OptionsFrame(self, self.plot_frame)
CodePudding user response:
self.winfo_toplevel()
will get you to the main window, so the below should do what you need. I find this method much easier than working backwards through .master
. Also, if you ever further nest your classes, you will have to add another master
to all the master.master.master
spots. This is going to get the top level window that the current widget belongs to, and never needs to be modified, regardless of how deep you bury a widget.
root = self.winfo_toplevel()
plot = root.plot_frame #or whatever you called it