I am trying to write a program that will display 4 rows of 2 columns with column 0 being labels and column 1 being entries. Then, pass those 4 integer entries through as arguments into a function when a button is left clicked. Here is my code so far:
from tkinter import *
root = Tk()
class ClassName():
def __init__(self, master):
self.run_button = Button(self.master, text="Button Text", bg="green", fg="black",
command="HERE IS WHERE I NEED HELP")
self.run_button.grid(row=4, columnspan=2)
self.label1 = Label(master, text="Entry 1").grid(row=0, sticky=E)
self.label2 = Label(master, text="Entry 2").grid(row=1, sticky=E)
self.label3 = Label(master, text="Entry 3").grid(row=2, sticky=E)
self.label4 = Label(master, text="Entry 4").grid(row=3, sticky=E)
self.entry1 = Entry(master).grid(row=0, column=1, sticky=W)
self.entry2 = Entry(master).grid(row=1, column=1, sticky=W)
self.entry3 = Entry(master).grid(row=2, column=1, sticky=W)
self.entry4 = Entry(master).grid(row=3, column=1, sticky=W)
I want to then take the 4 entries and pass them through a different function called the_function
. All the_function
does is print out something based on the values of the 4 entries. So my remaining code looks like this:
def the_function(self, a, b, c, d):
# Ensure a, b, c, and d are integers,
# do some math on the numbers and print something out based on the
# values of a, b, c and d.
irrelevant_variable = ClassName(root)
root.mainloop()
The function works properly without the GUI but I cannot figure out how to create a button that takes self.entry1
and passes it through as a
in the_function
.
Other posts have lead me to think I should use the lambda
command, but I'm not sure how this would work within this function.
You're on the right track - lambda
allows you to define an anonymous, in-line function:
...command=lambda: the_function(entry1.get(), entry2.get(), entry3.get(), entry4.get())
It basically acts as a wrapper. You could also do this:
def mywrapper(self):
the_function(entry1.get(), entry2.get(), entry3.get(), entry4.get())
And then bind that to the button:
...command=self.mywrapper)
Alternatively, simply have the_function
get the necessary variables itself:
def the_function(self):
a = entry1.get()
b = entry2.get()
c = entry3.get()
d = entry4.get()
# Ensure a, b, c, and d are integers
And bind that function without a lambda:
...command=self.the_function)
However, this won't help in your current code - chaining your geometry management methods onto your widget creation when you're actually interested in referencing the widget will cause a problem. The widget constructors (Button()
, Entry()
, etc.) will return that widget for future reference. However, the geometry management methods (grid()
, pack()
, etc.) simply act on their widget and return None
. This means that you're assigning None
to self.label1
, self.entry1
, and so on. Separate the widget creation from the geometry management:
self.label1 = Label(master, text="Entry 1")
self.label1.grid(row=0, sticky=E)
You will now have actual widgets to work with.