0

So I'm trying to use some entry widgets in tkinter and then use a function that does multiple .get() commands at the same time. However I get an error that the function is not defined, even though they are within the same class. Here's the samples of the code:

def GetSubjects():
        subject1 = subject1entry.get()
        subject2 = subject2entry.get()
        subject3= subject3entry.get()
subjectConfirm.grid(row=3, column=0, command=GetSubjects)

As I said these are both in the same class and yet the button cannot call the function. I am relatively new to tkinter and this site so forgive me if this is easy stuff, but I just couldn't find a solution anywhere else.

Edit: Here's the whole class, I know my code is probably very suboptimal but this is my first large project I've tried

class Menu:

    def __init__(self, master):
        frame = tk.LabelFrame(master, text="Main Menu", padx=100, pady=10)
        frame.grid(row=0, column=0, padx=15, pady=15)
        # Create timetable button
        createTimetable = tk.Button(frame, text="Create Timetable", command=self.CreateTimetable)
        createTimetable.grid(row=0, column=0)
        # Exit program button
        exitProgram = tk.Button(frame, text="Exit Program", command=self.CloseWindow)
        exitProgram.grid(row=1, column=0)

    def CloseWindow(self):
        root.destroy()

    def GetSubjects():
        subject1 = subject1entry.get()
        subject2 = subject2entry.get()
        subject3 = subject3entry.get()

    def CreateTimetable(self):
        tableWindow = tk.Toplevel(root)
        tableWindow.title('Timetable Maker Window')
        tableWindow.geometry("800x500+400+200")
        # Subject labels
        subjectlabel1 = tk.Label(tableWindow, text="Enter your first subject:")
        subjectlabel2 = tk.Label(tableWindow, text="Enter your second subject:")
        subjectlabel3 = tk.Label(tableWindow, text="Enter your third subject:")
        # Subject entry boxes
        subject1entry = tk.Entry(tableWindow)
        subject2entry = tk.Entry(tableWindow)
        subject3entry = tk.Entry(tableWindow)
        # Puts subject entry boxes on screen
        subject1entry.grid(row=0, column=1)
        subject2entry.grid(row=1, column=1)
        subject3entry.grid(row=2, column=1)
        # Puts subject labels on screen
        subjectlabel1.grid(row=0, column=0)
        subjectlabel2.grid(row=1, column=0)
        subjectlabel3.grid(row=2, column=0)
        # Creates subject confirm button
        subjectConfirm = tk.Button(tableWindow,text="Press to confirm subjects")
        # Puts subject confirm button on screen
        subjectConfirm.grid(row=3, column=0, command=GetSubjects)
        print(subject1)
        print(subject2)
        print(subject3)
7
  • Can you provide a larger sample of your code, perhaps the entire class. I suspect you need to use self.subject1entry.get() rather than what you are doing currently but would need to see more to give a definite answer Commented Sep 28, 2020 at 9:41
  • "even though they are within the same class" Then why does the callback not have a self parameter? Did you mean in the same file? Is the function defined before you create the button? Also, why is command a parameter of grid and not the button constructor? Commented Sep 28, 2020 at 9:44
  • def GetSubjects() is not a valid instance function declaration inside class because instance function expects at least one argument, the instance itself. Also in order to access variables across class functions, the variable should be instance variable, like self.subject1entry (self is the instance argument). Commented Sep 28, 2020 at 9:46
  • Yeah I just noticed that @tobias_k, still doesn't work with it changed though. I added the whole class to the post so you might be able to figure out my poor coding lmao. Commented Sep 28, 2020 at 9:49
  • @scotty3785 I edited the whole class into the post ^ Commented Sep 28, 2020 at 9:53

1 Answer 1

1

Your GetSubjects() method should look like this

def GetSubjects(self):
    subject1 = self.subject1entry.get()
    subject2 = self.subject2entry.get()
    subject3 = self.subject3entry.get()

Your CreateTimetable method should look like this (incomplete but give you the right idea)

def CreateTimetable(self):
    # Code removed for clarity
    self.subject1entry = tk.Entry(tableWindow)
    self.subject2entry = tk.Entry(tableWindow)
    self.subject3entry = tk.Entry(tableWindow)

And your callback for the button should look like this

subjectConfirm = tk.Button(tableWindow,text="Press to confirm subjects", command=self.GetSubjects)

The properties/methods need to be part of the Menu class so you use self. to tell python to make these properties of the current class (self is the typical convention but could be anything as long as you are consistent).

Oh and the print(subject1) parts need to be at the end of the GetSubjects method instead of where they currently are.

Sign up to request clarification or add additional context in comments.

2 Comments

You can't actually put the command in grid, though, can you?
@tobias_k Good catch! Serves me right for only partially reading their code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.