I'm beginner for python and I tried to make a BMI calculator
but i have some problems with the input and output
I want to get input from self.Heighttypeand self.Weighttypeand give a output at self.BMI
And some tips to simply my coding?
from tkinter import *
import tkinter.messagebox
root = Tk()
root.resizable(0,0)
class win1:
def __init__(self, master):
self.master = master
master.title("BMI Calculator")
#
self.he = IntVar()
self.we = IntVar()
self.height = Label(master, text="ENTER Your Height(cm) Here:")
self.Heighttype = Entry(master, textvariable=self.he) #here
self.weight = Label(master,text="ENTER Your Weight(kg) Here:")
self.Weighttype = Entry(master, textvariable=self.we) #and here
#
self.ans = IntVar()
self.BMI = Label(master, textvariable=self.ans) #output here
self.credit = Button(master, text="Credit", command=self.credit_show)
self.result = Button(master, text="Result", command=self.calculation)
root.protocol('WM_DELETE_WINDOW', self.ask_quit)
self.close = Button(master, text="Close", command=self.ask_quit)
self.height.grid(sticky=E, padx=2, pady=4)
self.Heighttype.grid(row=0, column=1, columnspan=2, padx=2)
self.weight.grid(sticky=E, padx=2, pady=4)
self.Weighttype.grid(row=1, column=1, columnspan=2, padx=2)
self.BMI.grid(row=2, column=1, columnspan=2, padx=2)
self.credit.grid(row=3, sticky=W, padx=4 , pady=4)
self.result.grid(row=3, column=1, pady=4, sticky=W+E, padx=4)
self.close.grid(row=3, column=2, pady=4, sticky=W+E, padx=1)
def calculation(self):
# i want to get the user input from top and make calculation
# and make a output self.BMI = Label
def credit_show(self):
tkinter.messagebox.showinfo("Credit","Created by BlackLotus")
def ask_quit(self):
if tkinter.messagebox.askokcancel("Quit", "Do you want to Quit?"):
root.destroy()
apps = win1(root)
root.mainloop()
Someone help me please. Thanks a lot.
Use .get() and .set() on the IntVars to get the parameters and set the result:
def calculation(self):
m = self.we.get()
l = self.he.get()
bmi = # calculate the bmi here
self.ans.set(bmi)
Also, while it seems to work with an IntVar as well, it seems more reasonable to make ans a DoubleVar, i.e.:
self.ans = DoubleVar()
Related
I need a bit off help..
In the example below I have two optionsMenus, two entries, and some labels.
What I'm trying to do, is to divide my input from the entry by the labels value, choosen from the optionsMenu, and then show the new value in the next column. But I'm a bit stuck now and can't get it to work.
from tkinter import *
class App(Frame):
def __init__(self, root=None):
Frame.__init__(self, root)
self.materialPrice = {'Brick': 70, 'Rockwool': 50, 'Concrete': 20}
materialvariable1 = StringVar(self, root)
materialvariable1.set("Choose material")
materialvariable2 = StringVar(self, root)
materialvariable2.set("Choose materiale")
self.w1 = OptionMenu(root, materialvariable1, *self.materialPrice, command=self.displayPrice).grid(row=2,
column=0,
columnspan=1,
sticky='WE')
self.w2 = OptionMenu(root, materialvariable2, *self.materialPrice, command=self.displayPrice2).grid(row=3,
column=0,
columnspan=1,
sticky='WE')
self.var = IntVar()
self.var.set(float(0.00))
self.var2 = IntVar()
self.var2.set(float(0.00))
self.entry1 = Entry(root, textvariable=self.var).grid(row=2, column=1)
self.entry2 = Entry(root, textvariable=self.var2).grid(row=3, column=1)
self.priceVarLabel1 = IntVar()
self.priceVarLabel1.set(float(0.00))
self.priceVarLabel2 = IntVar()
self.priceVarLabel2.set(float(0.00))
self.priceVarValue1 = Label(root, textvariable=self.priceVarLabel1, relief='sunken').grid(row=2,
column=2,
columnspan=1,
sticky='WE')
self.priceVarValue2 = Label(root, textvariable=self.priceVarLabel2, relief='sunken').grid(row=3,
column=2,
columnspan=1,
sticky='WE')
self.label1 = Label(root, textvariable=self.displayResult).grid(row=2, column=3)
self.label2 = Label(root, textvariable=self.displayResult2).grid(row=3, column=3)
def displayPrice(self, value):
self.priceVarLabel1.set(self.materialPrice[value])
def displayPrice2(self, value):
self.priceVarLabel2.set(self.materialPrice[value])
def displayResult(self):
self.label1.set(self.entry1 / self.priceVarValue1)
def displayResult2(self):
self.label1.set(self.entry1 / self.priceVarValue1)
root = Tk()
app = App(root)
root.title("help")
root.mainloop()
Just add the division to your function:
def displayPrice(self, value):
self.priceVarLabel1.set(self.materialPrice[value] / self.var.get())
You may want to change the starting value to 1 so that you don't get a ZeroDivisionError right off the bat.
BTW, initializing a widget and laying it out on the same line is a well known bug source. Always use 2 lines.
# very bad:
self.entry1 = Entry(root, textvariable=self.var).grid(row=2, column=1)
# good:
self.entry1 = Entry(root, textvariable=self.var)
self.entry1.grid(row=2, column=1)
I'm trying to get the value of the radiobutton selcted and storing this int into a varable. It's my first tkinter project, so I'm sorry for my probably stupid mistakes...
from tkinter import *
from tkinter import ttk
select = "A"
def begin():
grand = Tk()
grand.title("Converter")
window.destroy()
frame = Frame(grand)
option = IntVar()
-> AttributeError: 'NoneType' object has no attribute '_root'
grandlabel = Label(frame, text="Choose the grand").grid(row=0, sticky=N, padx=5)
grand1 = Radiobutton(frame, text="Speed", variable=option, value=1, command=sel).grid(row=1, sticky=W)
grand2 = Radiobutton(frame, text="etc", variable=option, value=2, command=sel).grid(row=2, sticky=W)
submitgrand = Button(frame, text="Ok", command=unit).grid(row=3, sticky=W)
frame.pack()
grand.mainloop()
def sel():
global option
global select
select = option.get()
option = StringVar()
def unit():
unit = Tk()
global select
select = grandchosen
if (grandchosen == "Speed"):
Label(unit, text="Test").pack()
else:
Label(unit, text="Test2").pack()
unit.mainloop()
root = Tk()
frame = Frame(root)
welcome = ttk.Label(frame, text="Welcome!").grid(row=0, sticky=N, padx=10, pady=3)
okbutton = Button(frame, text="Ok", width=15, command=begin).grid(row=1, sticky=S, padx=20, pady=30)
frame.pack()
style = ttk.Style()
style.configure("TLabel", foreground="midnight blue", font="Times 19")
root.mainloop()
Would be great to get some help, thank you!
I am trying to get the input of what page number the user wants. They should type in a number, and click the submit button. To test it, I just want to print whatever they typed and then close the window. I've been following: http://effbot.org/tkinterbook/entry.htm as a guide, but I am stumped.
Why does
print(temp)
not print out a number to console?
right now it prints out:
<bound method IntVar.get of <tkinter.IntVar object at 0x000001FBC85353C8>>
I've cleaned up the code a little bit:
import sys
from file import *
from page import *
from view import View
import tkinter as tk
from tkinter import *
class ViewGui:
def __init__(self):
#Included in the class, but unrelated to the question:
self._file = File("yankee.txt", 25)
self.pages = self._file.paginate()
self.initial_list = self.pages[0].readpage(self._file.fo)
self.initial_string = ''.join(self.initial_list)
# Create root
self.root = Tk()
self.root.wm_title("yankee.txt - page 1")
# Create frame for buttons
self.bframe = Frame(self.root)
self.bframe.pack(side=BOTTOM, fill=X)
self.tbutton = tk.Button(self.bframe, text="Top", command=lambda a="top": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.bbutton = tk.Button(self.bframe, text="Bottom", command=lambda a="bottom": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.ubutton = tk.Button(self.bframe, text="Up", command=lambda a="up": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.dbutton = tk.Button(self.bframe, text="Down", command=lambda a="down": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.pbutton = tk.Button(self.bframe, text="Page", command=lambda a="page": self.pageclicks()).pack(side=LEFT, expand=1, fill=X)
self.qbutton = tk.Button(self.bframe, text="Quit", command=quit).pack(side=LEFT, expand=1, fill=X)
# Create and pack Text
self.T = Text(self.root, height=35, width=60, wrap=NONE)
self.T.pack(side=TOP, fill=X)
# Create and pack Scrollbar
self.S = Scrollbar(self.root, orient=HORIZONTAL, command=self.T.xview)
self.S.pack(side=BOTTOM, fill=X)
# Attach Text to Scrollbar
self.T.insert('1.0', self.initial_string)
self.T.config(xscrollcommand=self.S.set, state=DISABLED)
self.S.config(command=self.T.xview)
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = (a.entrytext.get)
print(temp)
def clicks(self, a):
print("you clicked clicks with the " + a)
self.root.wm_title(self._file.filename + " - Page " + self._file.buttonHandler(a))
if __name__ == "__main__":
vg = ViewGui()
vg.root.mainloop()
When you create a new window you should not use Tk(), you must use tk.Toplevel()
Must change:
pop = Tk()
to
pop = tk.Toplevel()
You should also use get(), not just get. Must change:
temp = (a.entrytext.get)
to
temp = a.entrytext.get()
Code:
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = tk.Toplevel()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = a.entrytext.get()
print(temp)
Made changes to these two methods and now it is working.
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop._entry = Entry(pop)
pop._entry.pack()
pop._entry.focus_set()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, _pop):
temp = _pop._entry.get()
print(temp)
_pop.destroy()
I'm trying to write a simple python gui in windows 8.1 using python 3.4.2.
I try to make a program to calculate a concentration (molarity = moles / liter) but in the GUI I create No answer appears in the Text widget but numbers appear in the command shell.
The calculations also don't seem to work because when I left the entry empty something was calculated (which should be impossible, even if empty Entries would evaluate to 0 it shouldn't be able to divide by 0) and it gives me these numbers .56494480.56494448.
I think the problem is in this part
def mol(self):
moli = float(input(self.grammi)) / float(input(self.peso_molecolare))
self.text.delete(0.0, END)
self.text(0.0, moli)
def mola(self):
conc = float(float(input(self.grammi)/ float(input(self.peso_molecolare))) / float(input(self.litri))
self.text.delete(0.0, END)
self.text.insert(0.0, conc)
If you want the entire code here it is
from tkinter import *
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.instuction = Label(self, text="inserisci i seguenti dati")
self.instuction.grid(row=0, column=0, columnspan=2, sticky=W)
self.grammi = Entry(self)
self.grammi.label = Label(self, text="grammi")
self.grammi.grid(row=1, column=1, sticky=W)
self.grammi.label.grid(row=1, column=0, sticky=W)
self.peso_molecolare = Entry(self)
self.peso_molecolare.label = Label(self, text="peso molecolare")
self.peso_molecolare.grid(row=2, column=1, sticky=W)
self.peso_molecolare.label.grid(row=2, column=0, sticky=W)
self.litri = Entry(self, text="litri")
self.litri.label = Label(self, text="litri")
self.litri.grid(row=3, column=1, sticky=W)
self.litri.label.grid(row=3, column=0, sticky=W)
self.moli_button = Button(self, text="calcolo moli", command=self.mol)
self.moli_button.grid(row=2, column=2, sticky=W)
self.conc_button = Button(self, text="concentrazione", command=self.mola)
self.conc_button.grid(row=3, column=2, sticky=W)
self.exit_button = Button(self, text="Exit", command=self.close_window)
self.exit_button.grid(row=4, column=2, sticky=W)
self.text = Text(self, width=35, height=5, wrap=NONE)
self.text.grid(row=4, column=0, columnspan=2, sticky=W)
def mol(self):
moli = float(input(self.grammi)) / float(input(self.peso_molecolare))
self.text.delete('1.0', END)
self.text.insert('1.0', moli)
def mola(self):
conc = float(float(input(self.grammi)) / float(input(self.peso_molecolare))) / float(input(self.litri))
self.text.delete('1.0', END)
self.text.insert('1.0', conc)
def close_window(self):
root.destroy()
root = Tk()
root.title("chimica")
root.geometry("400x200")
app = Application(root)
root.mainloop()
With Tkinter, to get the value inserted in an Entry widget you shouldn't use input but you have to use the get method like:
moli = float(self.grammi.get()) / float(self.peso_molecolare.get())
same goes for conc:
conc = float(self.grammi.get()) / float(self.peso_molecolare.get()) / float(self.litri.get())
The problem you have is that input will prompt for user input in the command shell, after asking the question that is between the parentheses. However, you put a reference to an Entry widget there. So what is printed (.56494480 and .56494448) are internal references to these widgets, not results of any calculation.
I must assume that you are using Tkinter. It might be that line numbers start at 1 and you are inserting at line 0. Also, indexes are strings, not floats.
Try altering your code to:
def mol(self):
moli = float(input(self.grammi)) / float(input(self.peso_molecolare))
self.text.delete('1.0', END)
self.text.insert('1.0', moli)
def mola(self):
conc = float(float(input(self.grammi)) / float(input(self.peso_molecolare))) / float(input(self.litri))
self.text.delete('1.0', END)
self.text.insert('1.0', conc)
Or you could just use self.text.insert(INSERT, conc) which will insert at the current insertion point.
I would like to know how to create a dynamic button that calls the function selected in a OptionMenu Widget.
In the penultimate line [-2], I substituted "command=daily_return" by "command=var" but it does not work.
Any suggestions?
Best
Working code
from Tkinter import *
import Tkinter
import tkMessageBox
master = Tk()
myvar_1 = IntVar()
myvar_2 = IntVar()
myvar_3 = StringVar()
myvar_4 = IntVar()
myvar_5 = IntVar()
myvar_6 = IntVar()
myvar_7 = IntVar()
#
def daily_return(*args):
print "The start date is ", var.get(), "+", myvar_1.get(),"-", myvar_4.get(), "-", myvar_6.get(), "and the end date is", myvar_2.get(),"-", myvar_5.get(), "-", myvar_7.get(), " for the stock ticker:", myvar_3.get(), "."
def cumulative_return(*args):
print "The start date is ", myvar_1.get(), "the cumulative return."
def value_at_risk(*args):
print "The start date is ", myvar_1.get(), "the value at risk."
Label(master, text="Start Date (DD-MM-YYYY)").grid(row=0)
Label(master, text="End Date (DD-MM-YYYY)").grid(row=1)
Label(master, text="Stock Ticker").grid(row=2)
##
text_entry_1 = Entry(master, textvariable=myvar_1)
text_entry_1.pack()
text_entry_2 = Entry(master, textvariable=myvar_2)
text_entry_2.pack()
text_entry_3 = Entry(master, textvariable=myvar_3)
text_entry_3.pack()
text_entry_4 = Entry(master, textvariable=myvar_4)
text_entry_4.pack()
text_entry_5 = Entry(master, textvariable=myvar_5)
text_entry_5.pack()
text_entry_6 = Entry(master, textvariable=myvar_6)
text_entry_6.pack()
text_entry_7 = Entry(master, textvariable=myvar_7)
text_entry_7.pack()
#
var = StringVar()
var.set('Choose function')
choices = ['cumulative_return', 'daily_return', 'value_at_risk']
option = OptionMenu(master, var, *choices)
option.pack()
##
text_entry_1.grid(row=0, column=1)
text_entry_2.grid(row=1, column=1)
text_entry_3.grid(row=2, column=1)
text_entry_4.grid(row=0, column=2)
text_entry_5.grid(row=1, column=2)
text_entry_6.grid(row=0, column=3)
text_entry_7.grid(row=1, column=3)
option.grid(row=4, column=0)
sf = "Quant Program"
#
def quit():
global root
master.destroy()
#
master.title("Quant Program")
Button(master, text='Quit', command=quit).grid(row=4, column=4, sticky=W, pady=4)
Button(master, text='Show', command=daily_return).grid(row=4, column=1, sticky=W, pady=4)
mainloop( )
Sometimes the simplest solution is Good Enough:
def do_something():
# define a mapping from the choice value to a function name
func_map = {
"daily_choices": daily_choices,
"value_at_risk": value_at_risk,
"cumulative_return": cumulative_return,
}
# using the map, get the function
function = func_map[var.get()]
# call the function
function()
...
Button(..., command=do_something)