Reputation: 733
Please forgive me in advance, as I am very new to Python. I'm putting together this code for a very simple rate calculator and want to make it where when the Enter key is pressed the program calculates the total (executes the calculate command). Python returns an error saying that Calculate is not defined, however I've defined it several lines above. Any ideas?
import tkinter
from tkinter import ttk
from tkinter import *
root = Tk()
root.withdraw()
class Adder(ttk.Frame):
"""The adders gui and functions."""
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.init_gui()
def on_quit(self):
"""Exits program."""
quit()
def calculate(self, *args):
"""Calculates the sum of the two inputted numbers."""
num1 = int(self.num1_entry.get())
num2 = float(self.num2_entry.get())
num3 = ((num1/2000) * num2)
self.answer_label['text'] = num3
def init_gui(self):
self.root.title('Rate Calculator')
self.root.option_add('*tearOff', 'FALSE')
self.grid(column=0, row=0, sticky='nsew')
self.menubar = tkinter.Menu(self.root)
self.menu_file = tkinter.Menu(self.menubar)
self.menu_file.add_command(label='Exit', command=self.on_quit)
self.menu_edit = tkinter.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menu_file, label='File')
self.menubar.add_cascade(menu=self.menu_edit, label='Edit')
self.root.config(menu=self.menubar)
self.num1_entry = ttk.Entry(self, width=5)
self.num1_entry.grid(column=1, row = 2)
self.num2_entry = ttk.Entry(self, width=5)
self.num2_entry.grid(column=3, row=2)
self.calc_button = ttk.Button(self, text='Calculate',
command=self.calculate)
self.calc_button.grid(column=0, row=3, columnspan=4)
self.answer_frame = ttk.LabelFrame(self, text='Answer',
height=100)
self.answer_frame.grid(column=0, row=4, columnspan=4, sticky='nesw')
self.answer_label = ttk.Label(self.answer_frame, text='')
self.answer_label.grid(column=0, row=0)
# Labels that remain constant throughout execution.
ttk.Label(self, text='Rate Calculator').grid(column=0, row=0,
columnspan=4)
ttk.Label(self, text='Weight').grid(column=0, row=2,
sticky='w')
ttk.Label(self, text='Rate').grid(column=2, row=2,
sticky='w')
ttk.Separator(self, orient='horizontal').grid(column=0,
row=1, columnspan=4, sticky='ew')
for child in self.winfo_children():
child.grid_configure(padx=5, pady=5)
root.bind('<Return>', calculate)
if __name__ == '__main__':
root = tkinter.Tk()
Adder(root)
root.mainloop()
Upvotes: 1
Views: 4345
Reputation: 55469
I've reorganised your code slightly so it now calls the calculate
method either when you press the button or when you hit Enter.
import tkinter as tk
from tkinter import ttk
class Adder(ttk.Frame):
"""The adders gui and functions."""
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.init_gui()
def on_quit(self):
"""Exits program."""
tk.quit()
def calculate(self, *args):
"""Calculates the sum of the two inputted numbers."""
num1 = int(self.num1_entry.get())
num2 = float(self.num2_entry.get())
num3 = ((num1/2000) * num2)
self.answer_label['text'] = num3
def init_gui(self):
self.root.title('Breakbulk Rate Calculator')
self.root.option_add('*tearOff', 'FALSE')
self.grid(column=0, row=0, sticky='nsew')
self.menubar = tk.Menu(self.root)
self.menu_file = tk.Menu(self.menubar)
self.menu_file.add_command(label='Exit', command=self.on_quit)
self.menu_edit = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menu_file, label='File')
self.menubar.add_cascade(menu=self.menu_edit, label='Edit')
self.root.config(menu=self.menubar)
self.num1_entry = ttk.Entry(self, width=5)
self.num1_entry.grid(column=1, row = 2)
self.num2_entry = ttk.Entry(self, width=5)
self.num2_entry.grid(column=3, row=2)
self.calc_button = ttk.Button(self, text='Calculate',
command=self.calculate)
self.calc_button.grid(column=0, row=3, columnspan=4)
self.answer_frame = ttk.LabelFrame(self, text='Answer',
height=100)
self.answer_frame.grid(column=0, row=4, columnspan=4, sticky='nesw')
self.answer_label = ttk.Label(self.answer_frame, text='')
self.answer_label.grid(column=0, row=0)
# Labels that remain constant throughout execution.
ttk.Label(self, text='Breakbulk Rate Calculator').grid(column=0, row=0,
columnspan=4)
ttk.Label(self, text='Weight').grid(column=0, row=2,
sticky='w')
ttk.Label(self, text='Rate').grid(column=2, row=2,
sticky='w')
ttk.Separator(self, orient='horizontal').grid(column=0,
row=1, columnspan=4, sticky='ew')
for child in self.winfo_children():
child.grid_configure(padx=5, pady=5)
self.root.bind('<Return>', lambda event: self.calculate())
if __name__ == '__main__':
root = tk.Tk()
Adder(root)
root.mainloop()
To create a callback with the proper signature for .bind
I've used a lambda function that simply discards the Event object that gets passed to it.
I also got rid of the evil from tkinter import *
wildcard import.
Upvotes: 1
Reputation: 179
The problem is coming from this part of your code
root.bind('<Return>', calculate)
change it to
root.bind('<Return>', self.calculate)
it will work.
Upvotes: 0