Tkinter and ttk python2.7 - python

i found this code online and i wanted to try it out because im trying to figure out how to have my label to change while i type things into my messagebox. I tried the getmethod but i have been struggling with using it. So i found this code and when i tried it i get the error that ttk is undefined but it clearly is.
from Tkinter import *
from ttk import *
def calculate(*args):
try:
value = float(feet.get())
meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
except ValueError:
pass
root = Tk()
root.title("Feet to Meters")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
feet = StringVar()
meters = StringVar()
feet_entry = ttkEntry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))
ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=3, row=3, sticky=W)
ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="is equivalent to").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="meters").grid(column=3, row=2, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', calculate)
root.mainloop()
Traceback (most recent call last):
File "tk8.py", line 15, in
mainframe = ttk.Frame(root, padding="3 3 12 12")
NameError: name 'ttk' is not defined

So i found this code and when i tried it i get the error that ttk is
undefined but it clearly is.
You're star-importing from the module, though, using from ttk import *, so the name ttk doesn't refer to anything. For example, from math import * would bring sin, cos, etc., all into your namespace but the name math would still be undefined. The code works for me if I switch the imports to
from Tkinter import *
import ttk
and add the missing . from ttk.Entry in this line:
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)

You are looking for the trace_variable method. Here is a fixed version:
from Tkinter import Tk, StringVar
import ttk
def calculate(*args):
try:
value = float(feet.get())
meters.set('%g' % (0.3048 * value))
except ValueError:
if not feet.get():
meters.set('')
root = Tk()
root.title("Feet to Meters")
feet = StringVar()
feet.trace_variable('w', calculate)
meters = StringVar()
main = ttk.Frame(root)
main.grid(sticky='nsew')
ttk.Label(main, text="Feet:").grid(row=0, sticky='e')
feet_entry = ttk.Entry(main, width=7, textvariable=feet)
feet_entry.grid(row=0, column=1, sticky='ew')
feet_entry.focus()
ttk.Label(main, text="Meters:").grid(row=1, sticky='e')
ttk.Label(main, textvariable=meters).grid(row=1, column=1, sticky='ew')
root.mainloop()

Related

Tkinter - Printnig return function in a label

i don't really undestand, why the "results" label is not updating when i click on the button.
If someone can help me to understand!
Thank You
from tkinter import *
from tkinter import ttk
def add_function():
results.config(n1.get() + n2.get())
root = Tk()
root.geometry("500x100") # Size of the window
root.title("Add Calculator") # Title of the window
main_frame = ttk.Frame(root, padding="3 3 12 12")
main_frame.grid(column=0, row=0, sticky=(N,S,E,W))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
n1 = DoubleVar()
n1_entry = Entry(main_frame, width= 10, textvariable= n1)
n1_entry.grid(column=2, row=1, sticky=(N))
symbol_add = Label(main_frame, text="+")
symbol_add.grid(column=3, row=1, sticky=(N))
n2 = DoubleVar()
n2_entry = Entry(main_frame, width= 10, textvariable= n2)
n2_entry.grid(column=4, row=1, sticky=(N))
symbol_equal = Button(main_frame, width=10, text="=", command= add_function )
symbol_equal.grid(column=5, row=1, sticky=(N))
results = Label(main_frame, text=add_function(), background="#C0C0C0")
results.grid(column=6, row=1, sticky=(N))
root.mainloop()
I've tryed different variant, but it's either i have an error, or the label is printing a random number even before i modify the entry.
It is because you don't update the label. Returning something from a button command is pointless because the caller isn't your code. It's called from mainloop and mainloop doesn't know what to do with the return code.
To update the label you must call the configure method:
results.configure(text=n1.get() + n2.get())

Ttk label not displaying TextVar

I'm making a GUI with Tkinter (Tcl/Tk version 8.6.12) on Python 3.9. Up until now, I mostly had experience with pure Tk, but wanted to try Ttk out. My problem is that running:
someText = tk.StringVar(value="Some Text")
ttk.Label(mainframe, textvariable=someText).grid(column=0, row=0, sticky=(W, E))
does reserve some space for the string, but doesn't display it. When using the tk.Label class, it works like a charm...
What am I doing wrong, or is the ttk.Label class broken?
EDIT: here is my full MNWE (I wrapped everything in a function because I will need to integrate everything with some other code I have already written and this is the best way I've found to do it):
from tkinter import *
from tkinter import ttk
def generateGUI():
# Generates the main window
root = Tk()
root.title("Some interesting title")
root.resizable(FALSE, FALSE)
# Adds a frame for themed tk
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1) # setup the frame to scale with the window horizontally
root.rowconfigure(0, weight=1) # setup the frame to scale with the window vertically
# Creates a canvas
canv = Canvas(mainframe, bg="green")
canv.grid(column=0, row=0, sticky=(N, E, S, W))
# Sets some information panel up
info = ttk.Frame(mainframe)
info.grid(column=1, row=0, sticky=(N, E))
title = StringVar(value="<title>")
text1 = StringVar(value="<text1>")
text2 = StringVar(value="<text2>")
text3 = StringVar(value="<text3>")
# Adds the different labels
ttk.Label(info, font=25, textvariable=title).grid(column=0, row=0, sticky=N, columnspan=2)
ttk.Label(info, text="Info 1: ").grid(column=0, row=1, sticky=W)
ttk.Label(info, text="Info 2: ").grid(column=0, row=2, sticky=W)
ttk.Label(info, text="Info 3: ").grid(column=0, row=3, sticky=W)
ttk.Label(info, textvariable=text1).grid(column=1, row=1, sticky=E)
ttk.Label(info, textvariable=text2).grid(column=1, row=2, sticky=E)
ttk.Label(info, textvariable=text3).grid(column=1, row=3, sticky=E)
for child in mainframe.winfo_children():
child.grid_configure(padx=5, pady=5)
return root
gui = generateGUI()
gui.mainloop()
Your instance of StringVar is a local variable. Make it/them an instance variable if you're using classes, or a global variable if not.
def generateGUI():
global title
...
title = StringVar(value="<title>")
ttk.Label(info, font=25, textvariable=title)
This example code is working. You need to import ttk and change remove sticky.
why_no_sticky - good example on the link how grid works.
from tkinter import ttk
import tkinter as tk
mainframe = tk.Tk()
someText = tk.StringVar(value="Some Text")
label1 = ttk.Label(mainframe, textvariable=someText)
label1.grid(column=0, row=0)
mainframe.mainloop()

Python: Costing calculator output

Good day all
I'm busy creating a small costing calculator for the signage department.
I'm not getting the calculator to output the amount.
Brief Description:
You enter the height and width and then when you hit enter it needs to display the cost.
How do I get it to work? Any suggestions please and thanks.
from tkinter import *
from tkinter import ttk
#Define the Functions here
def squeare(height,width):
cost = ((float(height) * float(width))/1000000 * 650 * 1.15 * 1.50)
return cost
window = Tk()
window.title("Costing Calculator V1.0")
mainframe = ttk.Frame(window, padding="20 20 20 20")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
window.columnconfigure(0, weight=1)
window.rowconfigure(0, weight=1)
height = StringVar()
width = StringVar()
#ttk.Label(mainframe, text="H").grid(column=1, row=1, sticky=E)
height_entry = ttk.Entry(mainframe, width=7, textvariable=height)
height_entry.grid(column=3, row=1, sticky=(W,E))
ttk.Label(mainframe, text="X").grid(column=5, row=1, sticky=E)
#ttk.Label(mainframe, text="W").grid(column=6, row=1, sticky=E)
width_entry = ttk.Entry(mainframe, width=7, textvariable=width)
width_entry.grid(column=7, row=1, sticky=(W,E))
ttk.Label(mainframe, text="=").grid(column=8, row=1, sticky=E)
#call function
#squeare()
window.mainloop()
I have bound the window frame with the return key. There is an empty result label. Whenever you press the enter key, its text will be updated.
from tkinter import *
from tkinter import ttk
def squeare(height, width):
cost = float(height) * float(width)/1000000 * 650 * 1.15 * 1.50
result.configure(text=str(cost))
window = Tk()
window.title("Costing Calculator V1.0")
mainframe = ttk.Frame(window, padding="20 20 20 20")
mainframe.grid(column=0, row=0, sticky="nsew")
window.columnconfigure(0, weight=1)
window.rowconfigure(0, weight=1)
height = StringVar()
height.set(0)
width = StringVar()
width.set(0)
height_entry = ttk.Entry(mainframe, width=7, textvariable=height)
height_entry.grid(column=0, row=0, sticky="we")
ttk.Label(mainframe, text="X").grid(column=1, row=0, sticky="e")
width_entry = ttk.Entry(mainframe, width=7, textvariable=width)
width_entry.grid(column=2, row=0, sticky=(W,E))
ttk.Label(mainframe, text="=").grid(column=3, row=0, sticky="e")
result = ttk.Label(mainframe)
result.grid(row=0, column=4)
window.bind('<Return>', lambda e: squeare(height.get(), width.get()))
window.mainloop()
The is to catch the 'enter' event for the second input field.
from tkinter import *
from tkinter import ttk
#Define the Functions here
def squeare(height,width):
cost = ((float(height) * float(width))/1000000 * 650 * 1.15 * 1.50)
result.configure(text=str(cost))
def enter(event=None):
squeare(height.get(), width.get())
window = Tk()
window.title("Costing Calculator V1.0")
mainframe = ttk.Frame(window, padding="20 20 20 20")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
window.columnconfigure(0, weight=1)
window.rowconfigure(0, weight=1)
height = StringVar()
width = StringVar()
#ttk.Label(mainframe, text="H").grid(column=1, row=1, sticky=E)
height_entry = ttk.Entry(mainframe, width=7, textvariable=height)
height_entry.grid(column=3, row=1, sticky=(W,E))
ttk.Label(mainframe, text="X").grid(column=5, row=1, sticky=E)
#ttk.Label(mainframe, text="W").grid(column=6, row=1, sticky=E)
width_entry = ttk.Entry(mainframe, width=7, textvariable=width)
width_entry.grid(column=7, row=1, sticky=(W,E))
width_entry.bind('<Return>',enter)
ttk.Label(mainframe, text="=").grid(column=8, row=1, sticky=E)
result = ttk.Label(mainframe, text="")
result.grid(column=9, row=1, sticky=E)
window.mainloop()

tk code error, unsupported operand

The comments in the offending NewLevel function provide some explanation.
fuelstats.txt is a file with one number in it 94.5
When I run this code the error is:
unsupported operand - for float to StringVar
this is for new_level.set(fuel_level - kmltr), because one is a float but I've tried everything I can think of to change the types, I've even tried a get() maybe in the wrong way I don't know.
##call the tkinter module first with all libraries
##call the ttk module next but without all libraries so that
##I can use different lib as I need to
##...without the ttk lib I need to explicitly call the ttk function
from tkinter import *
from tkinter import ttk
##import fuel level from file
file = 'fuelstats.txt'
stats = open("fuelstats.txt").readlines()
##assign fuellevel to variable
fuel_level = stats[-1]
fuel_level = float(fuel_level)
ratekm = 2.5
###defining the calculate function here because it needs to be
###referenced early in the code
def calculate(*args):
value = float(km.get())
kmltr.set(value / ratekm)
##call the next function
NewLevel()
def NewLevel(*args):
global new_level
##this function does not work, it throws an exception
## that I cannot subtract a float from a stringVar
## this is obvious but how do I define the types properly?
new_level.set(fuel_level - kmltr)
def km_left():
global reserves
reserves = fuel_level * 2.5
n = 2
reserves = '{:.{}f}'.format(reserves, n)
root = Tk() ##set up main window container
root.title("Calculate Fuel")## give it a title
##next set up a frame widget which holds all the content
mainframe = ttk.Frame(root, padding="30 13 20 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
##these two lines tell tk to resize with main window
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
##define variables
km = StringVar()
kmltr = StringVar()
reserves = StringVar()
new_level = StringVar()
##call to functions
km_left()
##next create the three main widgets - input field for km
km_entry = ttk.Entry(mainframe, width=7, textvariable=km)
km_entry.grid(column=2, row=3, sticky=(W,E))
##the result fields (as labels) and the calculate button
ttk.Label(mainframe, text=fuel_level).grid(column=2, row=1, sticky=W)
ttk.Label(mainframe, text=reserves).grid(column=2, row=2, sticky=W)
ttk.Label(mainframe, textvariable=kmltr).grid(column=2, row=4, sticky=W)
ttk.Label(mainframe, text=new_level).grid(column=2, row=5, sticky=W)
ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=5, row=6, sticky=W)
##below I create labels for the widgets and place them in a the grid
ttk.Label(mainframe, text="km").grid(column=3, row=2, sticky=W)
ttk.Label(mainframe, text="litres").grid(column=3, row=1, sticky=E)
ttk.Label(mainframe, text="litres").grid(column=3, row=4, sticky=E)
ttk.Label(mainframe, text="fuel level is: ").grid(column=1, row=1, sticky=W)
ttk.Label(mainframe, text="fuel reserves = ").grid(column=1, row=2, sticky=W)
ttk.Label(mainframe, text="enter km traveled ").grid(column=1, row=3, sticky=W)
ttk.Label(mainframe, text="fuel used is: ").grid(column=1, row=4, sticky=W)
ttk.Label(mainframe, text="new fuel level is: ").grid(column=1, row=5, sticky=W)
##below is a loop to put padding around each field and widget
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
km_entry.focus() ##focus of the first field
root.bind('<Return>', calculate)##and allow the enter key to act as the button
root.mainloop()
##This final line tells Tk to enter its event loop,
## which is needed to make everything run.
You need to get the value inside the StringVar and then convert that to a float.
new_level.set(fuel_level - float(kmltr.get()))

Jump out in Tkinter loop

I am working on a Tkinter doesn't jump out problem.
There is what I am running:
from Tkinter import *
import ttk
def plus(*args):
value = float(a.get())
value1 = float(b.get())
result.set(value + value1)
print "the result is " + str(result.get())
root = Tk()
root.title("Plus them")
mainframe = ttk.Frame(root, padding="10 10 10 10")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
a = StringVar()
b = StringVar()
result = StringVar()
feet_entry = ttk.Entry(mainframe, width=5, textvariable=a)
feet_entry.grid(column=2, row=1, sticky=(W, E))
feet_entry1 = ttk.Entry(mainframe, width=5, textvariable=b)
feet_entry1.grid(column=5, row=1, sticky=(W, E))
ttk.Label(mainframe, text="the result is").grid(column=3, row=2, sticky=W)
ttk.Label(mainframe, textvariable = result).grid(column=5, row=2, sticky=(W, E))
ttk.Button(mainframe, text="Plus", command=plus).grid(column=3, row=3, sticky=W)
for child in mainframe.winfo_children():
child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', plus)
root.mainloop()
When it runs, it seems fine. But it doesn’t “jump out” no matter how many times I click the “Plus”, until I input new values for calculation and it still waiting for new entry.
How can I adjust to have it calculate only for once? Thanks.
To make your window execute only once and have plus button closing the window do as follow:
from Tkinter import *
import ttk
def plus(*args):
value = float(a.get())
value1 = float(b.get())
result.set(value + value1)
print "the result is " + str(result.get())
root.destroy() ####### look here !!!#######
root = Tk()
root.title("Plus them")
mainframe = ttk.Frame(root, padding="10 10 10 10")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
a = StringVar()
b = StringVar()
result = StringVar()
feet_entry = ttk.Entry(mainframe, width=5, textvariable=a)
feet_entry.grid(column=2, row=1, sticky=(W, E))
feet_entry1 = ttk.Entry(mainframe, width=5, textvariable=b)
feet_entry1.grid(column=5, row=1, sticky=(W, E))
ttk.Label(mainframe, text="the result is").grid(column=3, row=2, sticky=W)
ttk.Label(mainframe, textvariable = result).grid(column=5, row=2, sticky=(W, E))
ttk.Button(mainframe, text="Plus", command=plus).grid(column=3, row=3, sticky=W)
# for child in mainframe.winfo_children():
# child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', plus)
root.mainloop()
So here, in your plus callbeck you need to call root.destroy(). Also this loop for child in mainframe.winfo_children() does not make sense in my option, and its not needed. So I removed it in the example.

Categories

Resources