Python Forum
Using one child class method in another child class - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Using one child class method in another child class (/thread-39161.html)



Using one child class method in another child class - garynewport - Jan-11-2023

I have two child classes; GraphSelect and GraphCreate.

Both are children of the main, parent, class, App.

[inline]GrapgCreate[/inline] has a method...

    def change_graph(self, graph):
        if (graph == "G5"):
            self.cm_graph(sa_sun, t_sun)
        else:
            self.default_graph()
GraphSelect has (currently) radio buttons that, when selected, run one of it's own methods...

    def selection(self):
        graph_frame.change_graph(graph = self.radio_button_var)
The parent class (App) creates an instance of GraphFrame, called graph_frame...

        self.graph_frame = GraphFrame(self, header_name="Graph Section")
However, when I run this I get...

[inline]
graph_frame.change_graph(self, graph = self.radio_button_var)
NameError: name 'graph_frame' is not defined
[/inline]

I believe I need to direct it back to the parent object, but how?


RE: Using one child class method in another child class - Vadanane - Jan-11-2023

To do that, first, we need to create an object of “FirstClass” in the main method of the “SecondClass”. Once an object of the “FirstClass” is created, then we can invoke any method or attribute of the “FirstClass” within the “SecondClass” using that object.


RE: Using one child class method in another child class - garynewport - Jan-11-2023

(Jan-11-2023, 12:54 PM)Vadanane Wrote: To do that, first, we need to create an object of “FirstClass” in the main method of the “SecondClass”. Once an object of the “FirstClass” is created, then we can invoke any method or attribute of the “FirstClass” within the “SecondClass” using that object.

I get that (I think) and my parent class (the main/primary class of the program) has this...

import customtkinter
from GraphSelect import *
from GraphCreate import *

customtkinter.set_default_color_theme("blue")                                  # Themes: "blue" (standard), "green", "dark-blue"
customtkinter.set_appearance_mode("system")			                           # Appearance: "system" (standard), "dark", "light"
filenames = ['dummymain.lst']

class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        self.geometry("1000x1000")
        self.title("STELCOR Interface")

# create radio button frame 1 with print button
        self.graph_select_frame = GraphSelectFrame(self, header_name = "Graph Selections")
        self.graph_select_frame.grid(row = 0, column = 0, padx = 20, pady = 20)

        self.graph_frame = GraphFrame(self, header_name="Graph Section")
        self.graph_frame.grid(row = 0, column = 1, padx = 20, pady = 20)

if __name__ == "__main__":
    app = App()
    app.mainloop()
I have one object (graph_select_frame), that is created from GraphSelectFrame, the class where the radio buttons change instigates the trigger of...

    def selection(self):
        graph_frame.change_graph(self, graph = self.radio_button_var)
I have another object (graph_frame), that is created from GraphFrame, the class that needs to change the graph, given the selection from the other object...

    def change_graph(self, graph):
        if (graph == "G5"):
            self.cm_graph(sa_sun, t_sun)
        else:
            self.default_graph()
My problem is putting into practice what you have stated in theory. LOL


RE: Using one child class method in another child class - deanhystad - Jan-11-2023

I looked at your GraphCreate.py, GraphSelect.py and main.py files using links from this post: https://python-forum.io/thread-39150.html

You do not have a classes named GraphCreate, GraphSelect or main. You have files named GraphCreate.py and GraphSelect.py, but the classes are GraphFrame, GraphSelectFrame and App.
Names are important. Do not call something a class unless it is a class.

I would write your question like this:

I have this class named GraphSelectFrame. It is CTkFrame containing a bunch of radio buttons. When I press a button, I want to call a method named GraphFrame.change_graph(). GraphFrame is CTkFrame that contains a matplotlib plot. How do I connect my GraphSelectFrame object to my GraphFrame object?

I would solve this the same way as I would solve connecting a push button to a print statement, through a callback. GraphSelectFrame should not need to know anything about GraphFrame. When you push a button it should call a function. The function will be either a method of GraphSelectFrame, or it might be a method in your App class. The App class will know about both GraphSelectFrame and GraphFrame, so it will make the connection between the two.

I would add a button press callback to GraphSelectFrame.
class GraphSelectFrame(customtkinter.CTkFrame):
	
    def __init__(self, *args, header_name="GraphSelectFrame", **kwargs):
        <snip>
        self.callback = None
        self.radio_buttons = []
        for i, graph in enumerate(graphs):
            label, code, action = graph
            radio_button = customtkinter.CTkRadioButton(
                self,
                text=label,
                value=code,
                variable=self.radio_button_var,
                state=action,
                command=self.select_graph)
            radio_button.grid(row=i % 20, column=i // 20, padx=5, pady=5, sticky="W")
            self.radio_buttons.append(radio_button)

    def select_graph(self)
        if self.callback:
            self.callback(graphs[self.radio_button_var.get()])
In class App I would connect the GraphSelectFrame callback to the GraphFrame change_graph frunction.
class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        self.geometry("1024x768")
        self.title("STELCOR Interface")

# create radio button frame 1 with print button
        self.graph_select_frame = GraphSelectFrame(self, header_name="Graph Selections")
        self.graph_select_frame.grid(row=0, column=0, padx=20, pady=20)

        self.graph_frame = GraphFrame(self, header_name="Graph Section")
        self.graph_frame.grid(row=0, column=3, padx=20, pady=20)

        self.graph_select_frame.callback = self.graph_frame.change_graph
You should really do some more study of classes. You appear to be confused about the concept. Your GraphSelectFrame and GraphFrame classes are not children of app. App has instance attributes that are instances of these classes, but there is no class relationship other than whatever class relationship exitss between customtkinter.CTk and custometkinter.CTkFrame.


RE: Using one child class method in another child class - garynewport - Jan-11-2023

Thank you and, yes, I was confusing the names (which I should not have done).

And again, yes, I am seriously out of practice in the use of classes, etc. Mix that with trying to learn matplotlib, tkinter, customtkinter (originally tried Qt5 and Qt6), whilst doing other things alongside and, I am certainly confused (both linguistically and in their application).

I am reading around this but also using things like your help gives me something to work with.

Again, thank you; and I am seriously grateful.


RE: Using one child class method in another child class - garynewport - Jan-11-2023

OMG, I so rushed my original post!

I did know App was not a parent of the other classes - my brain was elsewhere! LOL