Reputation: 3117
I was trying to build something where I wanted to give separate class to each frames. Now when I called onSet function of AddWidgets class it shows an
ERROR: TypeError: onSet() missing 1 required positional argument: 'text'
What am I doing wrong? And how to solve this? My Code is given below:
import tkinter as tk
from tkinter import ttk
class MainWindow:
def __init__(self, master):
self.master = master
self.master.title("Class Function")
self.master.wm_iconbitmap('icon.ico')
self.master.geometry("360x240+100+100")
self.frame1 = ttk.Frame(self.master)
self.frame1.grid(row=0, column=0, padx=16, pady=16)
self.frame2 = ttk.Frame(self.master)
self.frame2.grid(row=0, column=1, padx=16, pady=16)
self.add = AddWidgets(self.frame1)
self.edit = EditWidgets(self.frame2)
class AddWidgets:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
self.label1 = ttk.Label(self.master, text="0")
self.label1.grid(row=0, column=0, padx=4, pady=4)
def onSet(self, text):
self.label1.configure(text=text)
class EditWidgets:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
def onEdit():
self.send_text = self.entry_text.get()
AddWidgets.onSet(self.send_text)
self.entry_text = tk.StringVar()
self.entry1 = ttk.Entry(self.master, textvariable=self.entry_text)
self.entry1.grid(row=0, column=0, padx=4, pady=4)
self.button1 = ttk.Button(self.master, text="edit", command=onEdit)
self.button1.grid(row=0, column=1, padx=4, pady=4)
def main():
root = tk.Tk()
app = MainWindow(root)
root.mainloop()
if __name__ == '__main__':
main()
I am new to Python and tkinter. I want to build a desktop app/software. I want to develop the software by following MVC pattern. So any resource for MVC in tkinter and suggestions on how can I improve my coding, software development process would be appreciated.
Upvotes: 1
Views: 969
Reputation: 2454
The method onSet
requires the instance of the class as a first argument, while you're only passing the text
argument. So when you call your onSet
method you should pass the instance of the AddWidgets
class as first argument.
You're instantiating this class in the MainWindow
class:
self.add = AddWidgets(self.frame1)
So you should pass the self.add
variable to the onSet
function. In order to do that you should have your EditWidget
class accept an additional parameter widget
:
class MainWindow:
def __init__(self, master):
self.master = master
self.master.title("Class Function")
self.master.wm_iconbitmap('icon.ico')
self.master.geometry("360x240+100+100")
self.frame1 = ttk.Frame(self.master)
self.frame1.grid(row=0, column=0, padx=16, pady=16)
self.frame2 = ttk.Frame(self.master)
self.frame2.grid(row=0, column=1, padx=16, pady=16)
self.add = AddWidgets(self.frame1)
self.edit = EditWidgets(self.frame2, self.add) <--Add parameter self.add
class AddWidgets:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
self.label1 = ttk.Label(self.master, text="0")
self.label1.grid(row=0, column=0, padx=4, pady=4)
def onSet(self, text):
self.label1.configure(text=text)
class EditWidgets:
def __init__(self, master, widget): <-- add parameter widget
self.master = master
self.create_widgets()
self.widget = widget
def create_widgets(self):
def onEdit():
self.send_text = self.entry_text.get()
self.widget.onSet(self.send_text) <--call onSet from widget instance
[...]
EDIT:
If you want to create different tabs, all with the same widgets, one approach could be the following: you create a MainWindow
class, where you add all the tabs to your window using the Notebook
class.
Then you create a Add Widgets
class that adds the required widgets to a frame. You instantiate this class on each of the created tabs, in order to populate them with the widgets.
In order to get the values of the variables you set in each tab you can write a method getEntryValue
(or whatever name) that returns the value set on the entry. Something like this:
class MainWindow:
def __init__(self, master):
self.master = master
self.master.title("Class Function")
self.master.geometry("360x240+100+100")
n = ttk.Notebook(master)
self.f1 = ttk.Frame(n) # Create first tab
self.f2 = ttk.Frame(n) # Create second tab
n.add(self.f1, text='One')
n.add(self.f2, text='Two')
n.pack()
self.widget1 = AddWidgets(self.f1)
self.widget2 = AddWidgets(self.f2)
class AddWidgets:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
def onEdit():
send_text = self.entry_text.get()
self.label1.configure(text = send_text)
self.label1 = ttk.Label(self.master, text="0")
self.label1.grid(row=0, column=0, padx=4, pady=4)
self.entry_text = tk.StringVar()
self.entry1 = ttk.Entry(self.master, textvariable=self.entry_text)
self.entry1.grid(row=0, column=1, padx=4, pady=4)
self.button1 = ttk.Button(self.master, text="edit", command=onEdit)
self.button1.grid(row=0, column=2, padx=4, pady=4)
def getEntryText(self):
return self.entry_text.get()
Hope it helps.
Upvotes: 1