Python Forum
[Tkinter] Troubles with accessing attr from other class - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: [Tkinter] Troubles with accessing attr from other class (/thread-29142.html)



[Tkinter] Troubles with accessing attr from other class - zarize - Aug-20-2020

Hi Guys,

I would like to make a "big button" which would load data in several tabs in my app.
In order to do this, i wanted create a function which would load 2nd part of the data, however, i can't access it.. i don't know why.

There is no problem to call the function, in that particular way it is working, but i would like to access it from other tab and then i can't make it.
    def test(self):
         
        self.historical_entry_market.insert(0, "asd")
I tried to run:
    def test(self):
         
        Comments_Tab(self).historical_entry_market.insert(0, "asd")
However it is not working..


Below are the codes for files
MAIN.py
import tkinter as tk
from tkinter.ttk import *
import pandas as pd
from rents import Rents_Tab
from comments import Comments_Tab

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.parent.geometry("700x700")
        
        self.notebook = Notebook(self)
        self.notebook.pack(fill="both", expand=True)
        
        #Tab name
        page1 = Rents_Tab(self.notebook)
        self.notebook.add(page1, text="Rents")
        page2 = Comments_Tab(self.notebook)
        self.notebook.add(page2, text="Comments")



if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
comments.py
import tkinter as tk
from tkinter.ttk import *
import pandas as pd


class Comments_Tab(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        
        #Headers
        self.header = Label(self, text="New Cycle(Current) ")
        self.header.grid(row=0, column=2)

        
        self.entry_label_market = Label(self, text="Market Trend: ")
        self.entry_label_market.grid(row=1, column=1)
        self.entry_market = Entry(self, width=30)
        self.entry_market.grid(row=1, column=2)
        
        self.entry_label_location = Label(self, text="Trend: ")
        self.entry_label_location.grid(row=2, column=1)
        self.entry_location = Entry(self, width=30)
        self.entry_location.grid(row=2, column=2)

        self.entry_label_survey = Label(self, text="Sources: ")
        self.entry_label_survey.grid(row=3, column=1)
        self.entry_survey = Entry(self, width=30)
        self.entry_survey.grid(row=3, column=2)
        
        ### Historical Data
        #Headers
        self.historical_header = Label(self, text="Historical ")
        self.historical_header.grid(row=0, column=3)
        #Labels
        self.historical_entry_market = Entry(self, width=30)
        self.historical_entry_market.grid(row=1, column=3)       

        self.historical_entry_location = Entry(self, width=30)
        self.historical_entry_location.grid(row=2, column=3)

        self.historical_entry_survey = Entry(self, width=30)
        self.historical_entry_survey.grid(row=3, column=3)
        
        #Buttons
        test_button = Button(self, text="Show Data", command=lambda: Comments_Tab.test(self))
        test_button.grid(row=5, column=3)
        
    def test(self):
        
        Comments_Tab(self).historical_entry_market.insert(0, "asd")



RE: [Tkinter] Troubles with accessing attr from other class - deanhystad - Aug-20-2020

You should only use Comments_Tab when creating an instance of Comments_Tab. Comments_Tab does not have any class or static resources, so everything should be called/referenced using an instance.

test_button = Button(self, text="Show Data", command=lambda: Comments_Tab.test(self))
should be
test_button = Button(self, text="Show Data", command=self.test)
def test(self):
        Comments_Tab(self).historical_entry_market.insert(0, "asd")
should be
def test(self):
        self.historical_entry_market.insert(0, "asd")
Why are you doing this
        page1 = Rents_Tab(self.notebook)
        self.notebook.add(page1, text="Rents")
        page2 = Comments_Tab(self.notebook)
        self.notebook.add(page2, text="Comments")
instead of this?
        self.notebook.add(Rents_Tab(self.notebook), text="Rents")
        self.notebook.add(Comments_Tab(self.notebook), text="Comments")
Or better yet add the pages in the tab classes:
# in main.py
        Rents_Tab(self.notebook, "Rents")
        Comments_Tab(self.notebook, "Comments")

#in comments.py
class Comments_Tab(tk.Frame):
    def __init__(self, parent, title, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        parent.add(self, text=title)



RE: [Tkinter] Troubles with accessing attr from other class - zarize - Aug-20-2020

I applied what you have written, thank you.

I want to create a function which will call few functions, but i can't get through it..

    def Few_Functions(self):
        self.Load_Data() ##Located in rents.py
        self.test()    ##Located in comments.py (that's why it cannot be called with self i guess?)
It returns:
Error:
AttributeError: 'Rents_Tab' object has no attribute 'historical_entry_market'
Which is true, because Load_Data() function is located in rents.py and the button is also placed right there, but i want to call function from other file and from other class. What can be done here?

My goal is to click 1 button which will call functions from the classes


RE: [Tkinter] Troubles with accessing attr from other class - deanhystad - Aug-20-2020

You really need to spend some time away from the computer thinking about how your program works. You need to document who knows what, who wants to use what, and how can they talk to each other. Right now your tabs only know about themselves. If they need to talk to MainApplication they have no way of doing so.

I would try very hard to make it so MainAppliction knows everything, the tabs know how to get what they need form MainAppliction, MainApplication has to know very little about the tabs, and none of the tabs have to know about each other.