I'm doing an assignment for a course and I'm not really sure what's up with the code but it runs without error, only displaying an empty window. I used an example given as a start and basically modified it to get this code. If needed I can provide the example code to compare.
from Tkinter import *
class App(Tk):
def __init(self):
Tk.__init__(self)
self.height()
self.weigh()
self.calculate()
self.output()
def height(self):
Label(self, text = "Enter Height, feet").grid()
self.feet = Entry(self)
self.feet.grid(row = 0, column = 1)
self.feet.insert(0, "100")
lblinches = Label(self, text = "Enter Height, inches")
lblinches.grid(row = 1, column = 0)
self.inches = Entry(self)
self.inches.grid(row = 1, column = 1)
def weigh(self):
Label(self, text = "Enter Weight").grid(row =2, column = 0)
self.weight = Entry(self)
self.weight.grid(row = 2, column = 1)
def output(self):
self.calcBMI = Button(self, text = "Calculate BMI")
self.calcBMI.grid()
self.calcBMI["command"] = self.calculate
Label(self, text = "Body Mass Index").grid(row = 4)
Label(self, text = "Status").grid(row = 5)
def calculate(self):
feet1 = int(self.feet.get())
inches1 = int(self.inches.get())
height1 = feet1 *12 + inches1
weight1 = int(self.weight.get())
bmi = (weight1 * 703) / (height1 * 2)
self.lblbmi["text"] = ".2f" % bmi
def main():
app = App()
app.mainloop()
main()
__init should be __init__. Since __init__ was not defined, none of the configuration methods were called.
Related
I am using Tkinter in Python 3 to create a converter between hex, binary and denary - while creating my own methods for conversions instead of using the built in methods.
I've completed the denary to binary conversion through the use of my 'highestPowerOf2' method in the DenToBin class. I want to use this method in my HexToBin class, but whenever I try to, an additional blank window pops up and I receive - AttributeError: 'NoneType' object has no attribute 'title' - error.
How would I run 'highestPowerOf2' in the HexToBin class?
(also sorry for any poor programming practise)
Code:
from tkinter import *
from functools import partial
class Menu(Frame):
def __init__(self, master= None): # initialise Menu
Frame.__init__(self, master) # initialise Frame
self.master = master # what does this do
self.createWindow()
def createWindow(self):
self.pack(fill = BOTH, expand = 1)
denToBin = Button(self, text = 'Denary to Binary', command = lambda: self.changeWindow(DenToBin))
denToBin.pack(fill = X, padx = 10, pady = 10)
hexToBin = Button(self, text = 'Hex to Binary', command = lambda: self.changeWindow(HexToBin))
hexToBin.pack(fill = X, padx = 10, pady = 10)
def changeWindow(self, object):
root.withdraw()
currentFrame = object(root)
class DenToBin(Toplevel):
def __init__(self, master = None):
Toplevel.__init__(self, master)
self.master = master
self.Window()
self.denary = 0
def Window(self):
# print(self.denary) -- Why is this not recognised?????????
self.master.title('Unit Converter: Denary to Binary')
instructionDen = Label(self, text = 'Denary Value: ')
instructionDen.grid(row = 1, column = 0, padx = 10)
instructionBin = Label(self, text = 'Binary Value: ')
instructionBin.grid(row = 2, column = 0, padx = 10)
self.denaryEntry = Entry(self)
self.denaryEntry.grid(row = 1, column = 2, padx = 10, pady = 5)
convertButton = Button(self, text = 'Convert!', command = lambda: self.highestPowerOf2(10)) # as an example
convertButton.grid(row = 3, column = 1)
# finds highest power of 2 that is less than denary number - helps self.convert()
def highestPowerOf2(self,number):
print('I find the highest power of 2 that fits into the number given.')
class HexToBin(Toplevel):
def __init__(self, master = None):
Toplevel.__init__(self, master)
self.master = master
self.Window()
self.denary = 0
def Window(self):
self.master.title('Unit Converter: Hexadecimal to Binary')
instructionHex = Label(self, text = 'Hexadecimal Value: ')
instructionHex.grid(row = 1, column = 0, padx = 10)
instructionBin = Label(self, text = 'Binary Value: ')
instructionBin.grid(row = 2, column = 0, padx = 10)
self.hexadecimalEntry = Entry(self)
self.hexadecimalEntry.grid(row = 1, column = 2, padx = 10, pady = 5)
convertButton = Button(self, text = 'Convert!', command = self.convert)
convertButton.grid(row = 3, column = 1)
def convert(self):
# I need to call the 'highestPowerOf2' method here.
pass
root = Tk()
unitConverter = Menu(root) # root is master
root.mainloop()
I was really curious why I cannot get my add_button to work,
as the window fails to come up when creating it.
from tkinter import *
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = 0
self.input2 = 0
input1 = Entry(master)
input2 = Entry(master)
input1.grid(row = 0, column = 1)
input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_buton = Button(master, text = "Add", command = self.add())
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
return self.input1.get() + self.input2.get()
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
#-------------------------------------------------
Welcome to Stack!
I've looked through you code I've been able to do what you are asking. There were a few errors within your code:
a) you had self.add_buton and self.add_button which caused an error.
b) self.input1 = 0 and self.input2 = 0 are not required.
c) You were calling self.add() as the command and you should be calling self.add. When calling it as a command you do not need ()
d)input1 = Entry(master) should be self.input1 = tk.Entry(master)
e) You should convert your input values into int or float as otherwise it will just one value onto the end of the other. (Eg, 1 + 5 = 15 whereas int(1) + int(5) = 6
Here is your code with the entry boxes working as they should. I have import tkinter as tk hence why it is tk.Entry
from tkinter import *
import tkinter as tk
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input2 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input1.grid(row = 0, column = 1)
self.input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_button = tk.Button(master, text = "Add", command = self.add)
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
val = self.input1.get()
print(val)
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
This should now work how you wanted it too. The variables within the entry can be changed to suit. You were correct in calling the value of the entry with self.input1.get().
Hope this has helped.
I really need help with some code. I don't expect you to write it for me, since it is a school project, but I am just really lost and need help.
The code I am writing is some sort of production system.
It doesn't need to actually be able to send a task anywhere, since this is just an imagined scenario.
The code has to consist of three files: data.py, model.py and gui.py.
Gui can access the two other files
Data can only access model
Model can't access either of the other two.
My teacher had written some of the code witch I have continued on. Some of the text is in danish, but most comments are in English.
The code is as follows.
data.py
from model import *
class Data(object):
def __init__(self):
self.units = []
self.finished_tasks = []
def __str__(self):
result = "These tasks have been finished: "
for i in self.finished_tasks:
result += str(i)
return result
def task_done(self, unit):
done_task = unit.task_done()
if done_task != None:
#TODO: add to list of finished tasks
pass
def add_task(self, name, amount, unit):
s = Springroll_task(name, amount)
unit.add_to_queue(s)
def read_from_database(self):#doesn't actually read from db..
self.units.append(Production_unit("maskine1"))
self.units.append(Production_unit("maskine2"))
self.add_task("Miniruller", 100, self.units[0])
self.add_task("Maxiruller", 200, self.units[0])
self.add_task("HowIRoll", 3000, self.units[0])
self.add_task("RulleMarie", 40, self.units[1])
self.add_task("Rullesten", 500, self.units[1])
self.add_task("Toiletpapirsruller", 6000, self.units[1])
model.py
class Springroll_task(object):
def __init__(self, name, amount):
self.name = name
self.amount = amount
def __str__(self):
return self.name + " " + str(self.amount)
class Production_unit(object):
def __init__(self, amount={}, name={},):
#name of the production unit
self.name = name
self.amount = amount
#the current task
self.current_task = None
#the tasks in the queue
self.springroll_queue = []
#the size of the queue
self.queue_size = 0
def __str__(self):
#TODO
return self.name + " " + str(self.amount)
def add_to_queue(self, task={}):
if self.current_task == None:
self.current_task = task
else:
self.springroll_queue.append(task)
self.queue_size += 1
#remember to update queue_size
pass
def task_done(self):
#TODO: remember the old current task.
#Set the current task to be the first in the queue (and remove from queue)
# - if there is a task in the queue.
#return the old current task.
#remember to update queue_size
self.queue_size -= 1
pass
gui.py
from tkinter import *
from model import *
from data import Data
class Application(Frame):
def __init__(self, master, unit):
self.mod = Production_unit()
super(Application, self).__init__(master)
self.grid()
self.unit = unit
self.create_widgets()
def create_widgets(self):
self.unit_name_lbl = Label(self, text = self.unit.name)
self.unit_name_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W)
self.cur_prod_lbl = Label(self, text = "produktion nu: ")
self.cur_prod_lbl.grid(row = 1, column = 0, columnspan = 2, sticky = W)
self.prod_lbl = Label(self, text = "produkt")
self.prod_lbl.grid(row = 2, column = 0, sticky = W)
self.amount_lbl = Label(self, text = "antal")
self.amount_lbl.grid(row = 2, column = 1, sticky = W)
#Label for production now
self.amount1_lbl = Label(self, text = " ", bg ="red")
self.amount1_lbl.grid(row = 3, column = 0, sticky = W)
self.amount2_lbl = Label(self, text = " ", bg ="red")
self.amount2_lbl.grid(row = 3, column = 1, sticky = W)
#Button for task finished
self.finished_but = Button(self, text = "Opgave afsluttet", bg ="pink", command=self.mod.task_done)
self.finished_but.grid(row = 3, column = 2, sticky = W)
#Label for queue
self.queue_lbl = Label(self, text = "Kø")
self.queue_lbl.grid(row = 4, column = 0, sticky = W)
#Label for production queue
for i in range(0,3):
self.name_lbl =Label(self, text = self.mod.springroll_queue, bg="red", width= 6)
self.name_lbl.grid(row = 5+i, sticky = W)
for j in range(0,3):
self.qt_lbl =Label(self, text = self.mod.springroll_queue, bg="red", width= 4)
self.qt_lbl.grid(row = 5+j, column = 1)
self.new_lbl = Label(self, text = "Ny")
self.new_lbl.grid(row = 10, column = 0, sticky = W)
#Entry for entries
self.eq1_ent = Entry(self, text = "", width=6)
self.entry_name = self.eq1_ent.get()
self.eq1_ent.grid(row = 11, sticky = W)
self.ea1_ent = Entry(self, text = "", width=4)
self.ea1_ent.grid(row = 11, column = 1, sticky = W)
#Button for add to queue
self.add_but = Button(self, text = "Tilføj til kø", bg ="pink", command=self.mod.add_to_queue(self.ea1_ent.get()))
self.add_but.grid(row = 11, column = 2, sticky = W)
def done(self):
d.task_done(self.unit)
self.redraw()
def add(self):
n = "Nyt navn" #read from gui
a = "Nyt antal" #read from gui
d.add_task(n, a, unit)
self.redraw()
def redraw(self):
#TODO
pass
# main
root = Tk()
root.title("Daloon")
root.geometry("300x300")
d = Data()
d.read_from_database()
p = d.units[0]
app = Application(root, p)
root.mainloop()
So it currently looks like this:
What I need to be able to do is to take an input in the bottom two entry widgets and put them in one of the 4 label widgets above, beginning from the top and then in the queue afterwards, this should happen when I press the button add_but, which seems to be gone currently.
After that I need the task stored in the data file when the "Opgave afsluttet" button is pressed.
I really hope someone is able to help me!
I edited it with some suggestions, and am calling the right self.eq1_ent.get() now, I think. I dont get any error any longer, now I just don't really know how to make it do what I want.
Edit 2: I am slowly getting some stuff, so i have made changes in the model.py and gui.py...
It looks like this now:
self.eq1 is not defined. you have self.q1_lbl and self.eq1_ent.
To access the label use self.q1_lbl.
To be able to set text to your label create them as following:
self.var = StringVar()
self.unit_name_lbl = Label(self, textvariable=self.var)
For example, from redraw() you can set 'text' to self.unit_name_lbl like this : self.var.set('text').
Check if you missed self in d.add_task(n, a, unit)
When you do command=mod.add_to_queue(self.ea1_ent.get()) the mod.add_to_queue function will be called directly, if you want to pass argument to this function when user press the button, you can use lambda:
command=lambda: mod.add_to_queue(self.ea1_ent.get)
I have a program that calculates a persons BMI after the user gives his height and weight.
I used variable.insert() to insert a value so the program doesn't have errors.
Is there any way to have the program start 'empty' without getting errors? Basically, I need it to not do anything until the calculate button is pressed.
from Tkinter import *
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.height()
self.weigh()
self.output()
self.calculate()
def height(self):
Label(self, text = "Enter Height, feet").grid()
self.feet = Entry(self)
self.feet.grid(row = 0, column = 1)
self.feet.insert(0, "1")
Label(self, text = "Enter Height, inches").grid(row = 1, column = 0)
self.inches = Entry(self)
self.inches.grid(row = 1, column = 1)
self.inches.insert(0, "1")
def weigh(self):
Label(self, text = "Enter Weight").grid(row =2, column = 0)
self.weight = Entry(self)
self.weight.grid(row = 2, column = 1)
self.weight.insert(0, "1")
def output(self):
self.calcBMI = Button(self, text = "Calculate BMI")
self.calcBMI.grid(row = 6, columnspan = 2)
self.calcBMI["command"] = self.calculate
Label(self, text = "Body Mass Index").grid(row = 4, column = 0)
self.lblbmi = Label(self, bg = "#fff", anchor = "w", relief = "groove")
self.lblbmi.grid(row = 4, column = 1, sticky = "we")
Label(self, text = "Status").grid(row = 5, column = 0)
self.lblstat = Label(self, bg = "#fff", anchor = "w", relief = "groove")
self.lblstat.grid(row = 5, column = 1, sticky = "we")
def calculate(self):
ft = int(self.feet.get())
inch = int(self.inches.get())
ht = ft * 12 + inch
wt = int(self.weight.get())
bmi = (wt * 703) / (ht ** 2)
self.lblbmi["text"] = "%.2f" % bmi
if bmi > 30:
self.lblstat["text"] = "Obese"
elif bmi > 25:
self.lblstat["text"] = "Overweight"
elif bmi > 18.5:
self.lblstat["text"] = "Normal"
else:
self.lblstat["text"] = "Underweight"
def main():
app = App()
app.mainloop()
if __name__ == "__main__":
main()
What you are doing right now is calling the output outright(& also by pressing the calculate button). What you need to do is call it only when the button is pressed
From init() remove self.calculate().
Now just remove all the insert statements. You don't need them anymore ;)
Edit:
As Joe suggested in his comment, you could also disable the button until all the fields are populated. You could do this by setting its state to disabled,like this:
self.calcBMI.config(state='disabled')
I'm a full time student, taking my first class in python.
This is so strange, it was working, and now, it is no longer showing the buttons, labels, and entry fields. I'm sure it was something I removed or added, but, I'm at a loss.
Any ideas? All suggestions are appreciated.
from Tkinter import *
import tkFont
import tkMessageBox
class BouncyGUI(Frame):
"""The GUI used to interface with the bouncy calculation from chapter 9 section 1."""
def __init__(self):
Frame.__init__(self)
# Establish the Base Frame
self.master.title("Calculate the Bounciness of a Ball")
self.master.rowconfigure(0, weight = 1)
self.master.columnconfigure(0, weight = 1)
self.master.grid()
self.master.resizable(0,0)
# Establish the components for capturing the Height
self._heightLabel = Label(self,
text = "Height of initial drop:",
justify = "left")
self._heightLabel.grid(row = 0, column = 0)
self._heightVar = DoubleVar()
self._heightEntry = Entry(self,
textvariable = self._heightVar,
justify = "center")
self._heightEntry.grid(row = 0, column = 1)
# Establish the "bounciness index"
self._bouncyIndex = Label(self,
text = "Bounciness Index:",
justify = "left")
self._bouncyIndex.grid(row = 1, column = 0)
self._bouncyVar = DoubleVar()
self._bouncyEntry = Entry(self,
textvariable = self._bouncyVar,
justify = "center")
self._bouncyEntry.grid(row = 1, column = 1)
self._bouncyVar.set(0.6)
# Establish number of allowable bounces
self._numberBounces = Label(self,
text = "Number of Bounces:",
justify = "left")
self._numberBounces.grid(row = 2, column = 0)
self._numberBouncesVar = IntVar()
self._numberBouncesEntry = Entry(self,
textvariable = self._numberBouncesVar,
justify = "center")
self._numberBouncesEntry.grid(row = 2, column = 1)
# Establish a field for the response
self._answer = Label(self,
text = "Distance Travelled",
justify = "left")
self._answer.grid(row = 3, column = 0)
self._answerVar = DoubleVar()
self._answerFont = tkFont.Font(weight="bold", size = 12)
self._answerEntry = Entry(self,
textvariable = self._answerVar,
justify = "center",
font = self._answerFont)
self._answerEntry.grid(row = 3, column = 1)
self._answerEntry.config(state = DISABLED, bg = "green")
# Create frame to hold buttons
self._buttonFrame = Frame(self)
self._buttonFrame.grid(row = 4, column = 0, columnspan = 2)
# Create Reset Button
self._buttonReset = Button(self._buttonFrame,
text = "Reset",
command = self._reset,
width = 15,
padx = 2,
pady = 2)
self._buttonReset.grid(row = 0, column = 0)
#self._buttonReset.config(state = DISABLED)
# Create Calculate Button
self._buttonCalc = Button(self._buttonFrame,
text = "Calculate",
command = self._calculate,
width = 15,
padx = 2,
pady = 2)
self._buttonCalc.grid(row = 0, column = 1)
#self._buttonCalc.config(state = NORMAL)
def _reset(self):
"""Allow for the screen to reset for fresh data entry."""
self._heightVar.set(0.0)
self._numberBouncesVar.set(0)
self._answerVar.set(0.0)
#self._buttonCalc.config(state = NORMAL)
#self._buttonReset.config(state = DISABLED)
#self._numberBouncesEntry.config(state = NORMAL)
#self._bouncyEntry.config(state = NORMAL)
#self._heightEntry.config(state = NORMAL)
def _calculate(self):
"""Calculate the bounciness and update the GUI"""
if self._validDataTypes():
self._answerVar.set(computeDistance(self._heightVar.get(), \
self._bouncyVar.get(), \
self._numberBouncesVar.get()))
#self._numberBouncesEntry.config(state = DISABLED)
#self._bouncyEntry.config(state = DISABLED)
#self._heightEntry.config(state = DISABLED)
#self._buttonCalc.config(state = DISABLED)
#self._buttonReset.config(state = NORMAL)
def _validDataTypes(self):
theMessage = ""
if self._isInt(self._numberBouncesVar.get()) != True:
theMessage += "Please re-enter Integer Value for Number of Bounces.\n"
elif self._isFloat(self._bouncyVar.get()) != True:
theMessage += "Please re-enter Float Value for Bounciness Index.\n"
elif self._isFloat(self._heightVar.get()) != True:
theMessage += "Please re-enter Float Value for Initial Height."
if len(message) > 0:
tkMessageBox.showerror(message = message, parent = self)
return False
else:
return True
def _isInt(self, value):
# Test to ensure that value entered is an integer
try:
x = int(value)
except ValueError:
# If not return false
return False
# if it is an integer, return true
return True
def _isFloat(self, value):
# Test to ensure that value entered is a float value
try:
x = float(value)
except ValueError:
# If not return false
return False
# If it is a float, return true
return True
def computeDistance(height, index, bounces):
"""Compute the distance travelled."""
total = 0
for x in range(bounces):
total += height
height *= index
total += height
return total
def main():
"""Run the main program"""
BouncyGUI().mainloop()
main()
Your main() function setup code isn't working properly. I'm not sure how you had it set up before, but one way to get it working is this:
def main():
"""Run the main program"""
root = Tk()
gui = BouncyGUI()
gui.pack()
root.mainloop()
You need to grid the main app, not just call its mainloop:
def main()
app = BouncyGUI()
app.grid()
app.mainloop()
there is an error in your code when compiling:
NameError: global name 'message' is not defined