Python Forum
[Tkinter] Use function from other class (Tkinter)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Use function from other class (Tkinter)
#1
Hi guys,

I would like to use function defined in main class, in another file/class - Rents.py/class Rents_tab(Frame)

MAIN.PY
import pandas as pd
from tkinter import *
from tkinter.ttk import *
from rents import *

class Application(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        #set window size
        parent.geometry("1600x1600")
        #Set the header of application
        parent.title("My first application")
        self.notebook = Notebook(self)
        self.notebook.grid(row=1, column=1)
        #DETERMINING TAB NAMES
        comment_tab = Comments_tab(self.notebook)
        rents_tab = Rents_tab(self.notebook)

        
        #Assign tab names
        self.notebook.add(rents_tab, text="Rents")
        def Load_Data(self):
            excel_file_mhs = pd.read_csv(r'C:\Users\USER\Desktop\project_))\September 2019.csv', encoding='cp1252')
            contr_select = excel_file_mhs.loc[excel_file_mhs['Country Name']== self.entry_country.get()]
            loca_select = contr_select.loc[contr_select['Location Name']== self.entry_location.get()]
            final_select = loca_select.loc[loca_select['Survey Date'] == self.entry_survey.get()]
            return final_select
Rents.py - In that file i want to use the function Load_Data()

import pandas as pd
from tkinter import *
from main import *
from tkinter.ttk import *

class Rents_tab(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        
        
        entry_label_country = Label(self, text="Please provide country: ")
        entry_label_country.grid(row=1, column=1)
        entry_country = Entry(self, width=30)
        entry_country.grid(row=1, column=2)
        entry_country.insert(0, "Poland") #Default displayed text
        
        entry_label_location = Label(self, text="Please provide location: ")
        entry_label_location.grid(row=2, column=1)
        entry_location = Entry(self, width=30)
        entry_location.grid(row=2, column=2)
        entry_location.insert(0, "Warsaw") #Default displayed text

        entry_label_survey = Label(self, text="Survey Date: ")
        entry_label_survey.grid(row=3, column=1)
        entry_survey = Entry(self, width=30)
        entry_survey.grid(row=3, column=2)
        entry_survey.insert(0, "2019") #Default displayed text
        
        # #Buttons
        test_button = Button(self, text="Show Data", command=Application().Load_Data)
        test_button.grid(row=3, column=3)
Could you please guide me, what i am doing wrong?

Using command=Application().Load_Data) gives me output
Error:
TypeError: __init__() missing 1 required positional argument: 'parent'
Using command=Application(self).Load_Data)
or
Using command=Application(parent).Load_Data) gives me output
Error:
AttributeError: 'Rents_tab' object has no attribute 'geometry'
Reply
#2
Note: Namespace flooding with * imports

def Load_Data(self): indentation should be level with def __init__(self, parent):

Error:
TypeError: __init__() missing 1 required positional argument: 'parent'
is because when doing the following
class Rents_tab(Frame):
    def __init__(self, parent):
creating an instance of Rents_tab expects to be passed a variable for the parameter parent

Error:
AttributeError: 'Rents_tab' object has no attribute 'geometry'
is because when doing the following
class Application(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        #set window size
        parent.geometry("1600x1600")
an instance of Rents_tab is passed in as the parent into Application
so when it calls parent.geometry("1600x1600"), Rents_tab does not have the attribute 'geometry'
Reply
#3
thank you :)

#EDIT

I have 1 more question... how can i access user's input from the Entry now?
If there is Entry in rents.py(another class)
entry_location.get()
How can i access it in main?
I thought that it could work but it dont:
print(Rents_tab.entry_location.get())
Reply
#4
Application has been passed an instance of Rents_tab as the parent parameter.
add parent as an attribute to Application
class Application(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
inside of Application to access Rents_tab's entry_location you can use
self.parent.entry_location.get()
Reply
#5
Thank you for your message.


I tried this:
    def test(self):
        print(self.parent.entry_location.get())
returned me:
Error:
AttributeError: 'Notebook' object has no attribute 'entry_location'
Reply
#6
You have Notebook set as the parent not Rents_tab
Reply
#7
I would really appreciate more explanation
Reply
#8
I think you have two problems. The first problem is that Load_Data is a function inside Application.__init__ when it should be a method of Application. I don't know if this is a design decision or if you just got the indentation wrong. But if you want to call Load_Data from outside __init__ it needs to be fixed.

The second problem is there is some confusion about the relationship between Application and Rents_Tab. Why is Load_Data in Application? As currently written I see no reason why Load_Data is not a method in Rents_tab. Are you planning on changing Load_Data in a way that makes it dependent upon Application? Often Notebook is used as a way to provide different views into some data, data that is shared by multiple tabs in the notebook. Is that what's going to happen here? If so, you are currently not set up for that type of relationship.

If Rents_tab is just a view into part of Application, you need to define the relationship between the two. As things currently are, Rents_tab knows nothing about Application. It doesn't even have a handle to talk to Application. If Appliction has resources that Rents_tab needs to use, you need to either make Application a subclass of Notebook, or pass an Application object as an argument to Rents_tab.__init__
    def __init__(self, parent_view, application):
        Frame.__init__(self, parent_view)
        self.application = application  # Keep reference to Application object?
        ...
        # #Buttons
        test_button = Button(self, text="Show Data", application.Load_Data)

         
Reply
#9
Thank you very much for your message :)
1)
Yes, it was by a mistake, i fixed it now.

2)My goal is to make an application which has a lot of tabs, and every single tab should have 1 seperate file designed for it(in general 9 tabs). Load_Data is in Application class, because i was thinking that it might be good to stack all functions in main file(Application class).
Purpose of this function is to gather data based on Entries provided by user and display it (later on)

3)
I wanted to treat Rents_tab as other 8 tabs, i would like to store the code down there and access it from the main class - Application
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  function in new window (tkinter) Dale22 7 248 Nov-24-2020, 11:28 PM
Last Post: Dale22
Star [Tkinter] How to perform math function in different page of Tkinter GUI ravaru 2 187 Oct-23-2020, 05:46 PM
Last Post: deanhystad
  Call local variable of previous function from another function with Python3 & tkinter Hannibal 5 313 Oct-12-2020, 09:16 PM
Last Post: deanhystad
  tkinter get method is not accepting value when called by function jagasrik 1 232 Sep-16-2020, 05:28 AM
Last Post: Yoriz
  Class function does not create command button Heyjoe 2 308 Aug-22-2020, 08:06 PM
Last Post: Heyjoe
  [Tkinter] Troubles with accessing attr from other class zarize 3 347 Aug-20-2020, 06:05 PM
Last Post: deanhystad
  [Tkinter] updating tkinter chart from within function mikisDW 1 318 Jul-02-2020, 03:33 AM
Last Post: deanhystad
  Passing arguments into function, tkinter nanok66 3 647 Apr-18-2020, 11:53 PM
Last Post: nanok66
  Tkinter:Unable to bind and unbind function with a button shallanq 2 771 Mar-28-2020, 02:05 AM
Last Post: joe_momma
  [PyQt] call a function with parametrs from another class atlass218 3 618 Feb-29-2020, 11:00 AM
Last Post: atlass218

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020