Reputation: 1103
I'm new to python and I am trying to do something like this: I have two classes, one for building a GUI form, and another class to handle the request. the submit button is on the GUI form, and the handle action is in the handle class.
So I tried to call the handle class from the GUI class, so I did something like this:
class Appview:
def __init__(self, master):
master.title("Simple EXCEL")
master.resizable(False, False)
self.filename = ""
self.input_file = ttk.Entry(self.frame_content, textvariable = self.filename, width = 24)
self.input_file.grid(row = 2, column = 1, pady = 5, padx = 5)
ttk.Button(self.frame_content, text = "choose file", command = self.browse_file).grid(row = 2, column = 2)
#ADDING#
a = HandleData(self)
ttk.Button(self.frame_content, text = "add", command = HandleData.submit).grid(row = 3, column = 0 ,columnspan = 3, pady = 5)
"""
Choosing a file to browse
"""
def browse_file(self):
self.filename = filedialog.askopenfilename(title = 'Choose a ffffile')
self.input_file.insert(0, self.filename) #updating the file entry
and this is the Handle class:
class HandleData:
def __init__(self):
self.the_file = Appview.filename.get()
def submit(self):
messagebox.showinfo(title = "Okie Dokie", message = "well done: {}".format(self.the_file))
but I keep getting this error:
Traceback (most recent call last):
File "C:\Users\Amir\workspace\Python Workout\main.py", line 91, in if __ name__ == "__ main__": main()
File "C:\Users\Amir\workspace\Python Workout\main.py", line 88, in main appview = Appview(root)
File "C:\Users\Amir\workspace\Python Workout\main.py", line 60, in __ init__ a = HandleData(self)
TypeError: __ init__() takes 1 positional argument but 2 were given
any ideas please?
Upvotes: 2
Views: 2814
Reputation: 90889
When you do -
a = HandleData(self)
You are trying to create the instance (object) of HandleData
, when creating an instance, the __init__()
is called (after the object has been created) with the first argument as the created instance itself, so when you send in self
, it becomes the second argument for __init__()
, but your __init__()
in HandleData
only accepts one argument , so the issue occurs.
You can make HandleData
accept a second parameter which could be the AppView and then in the HandleData.submit
, you can get the filename from this object. Example -
HandleData -
class HandleData:
def __init__(self, appview):
self.appview = appview
def submit(self):
filename = self.appview.filename
messagebox.showinfo(title = "Okie Dokie", message = "well done: {}".format(filename))
This gets the data for filename
from the instance variable filename
in AppView
, if you want the data from the Entry input_file
, you can use -
filename = appview.input_file.get()
Why the changes to submit()
and HandleData
are required is because we cannot get the filename when we do __init__()
itself, because you create the object for HandleData
in AppView.__init__()
, so you have not selected any filename till then. So instead you are saving the appview
object in self.appview
and when submit
button is clicked, you are accessing the filename
attribute set to it and doing your logic.
Change in AppView class -
self.datahandler = HandleData(self)
ttk.Button(self.frame_content, text = "add", command = self.datahandler.submit).grid(row = 3, column = 0 ,columnspan = 3, pady = 5)
Upvotes: 1
Reputation: 3691
You need and extra parameter in your __init__
function to hold the second class:
def __init__(self, other_class):
self.the_file = other_class.filename.get()
And then you can call it like you do:
a = HandleData(self)
Because in this case self
refers to the AppView
class. When in the HandleData
class' __init__
function it refers to the HandleData
class.
Look at the docs here about classes.
Upvotes: 0
Reputation: 11134
a = HandleData(self)
Look at this, what are you passing though self? A reference of the class, you are in. But HandleData
needs the reference of the class which it belong, and it automatically get it.
So, it basically gets 2 parameter, where 1 should be got.
Try:
a = HandleData()
Upvotes: 0