Related
I am trying to build a messaging system in a tkinter window, in which I'm using grid layout. I want to place a label on top for the messages, with an Entry right below it for people to type in; thus, I want them completely flush. I found pady and ipady which are supposed to do this, but even after setting both to 0:
Label(mainframe, background='white', text='asdasdasdasdasd', anchor=W, justify=LEFT, bd=1, relief='solid').grid(column=1, row=3, sticky=(W,E), columnspan=3, pady=0, ipady=0,padx=0,ipadx=0)
Entry(mainframe, background='white', bd=1, relief='sunken').grid(column=1, row=4, sticky=(W,E), columnspan=3, pady=0, ipady=0, padx=0,ipadx=0)
The code generates the image below, with space still inbetween the elements. Not sure how to fix this - all my googling tells me that all I should need to do is set pady and ipady to 0, but apparently this does not work. All help is appreciated.
EDIT:
Here's the full code:
from tkinter import *
root = Tk()
root.title("title")
mainframe = Frame(root)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
Label(mainframe, text='Left Label').grid(column=1, row=1, sticky=(W, E), rowspan=2)
Label(mainframe, background='white', text='asdasdasdasdasd', anchor=W, justify=LEFT, bd=1, relief='solid').grid(column=1, row=3, sticky=(W,E), columnspan=3, pady=0, ipady=0,padx=0,ipadx=0)
Entry(mainframe, background='white', bd=1, relief='sunken').grid(column=1, row=4, sticky=(W,E), columnspan=3, pady=0, ipady=0, padx=0,ipadx=0)
Label(mainframe, text="Center Area").grid(column=2, row=1, sticky=W, rowspan=2)
Label(mainframe, text="Right Label").grid(column=3, row=1, sticky=W, rowspan=2)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
root.mainloop()
You used for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) in the last.This will add the padding of each widget in the mainframe.
The fastest and easiest way to do that and don't change the padding of other widgets.Just change the sequence of your code:
from tkinter import *
root = Tk()
root.title("title")
mainframe = Frame(root)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
Label(mainframe, text='Left Label').grid(column=1, row=1, sticky=(W, E), rowspan=2)
Label(mainframe, text="Center Area").grid(column=2, row=1, sticky=W, rowspan=2)
Label(mainframe, text="Right Label").grid(column=3, row=1, sticky=W, rowspan=2)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
Label(mainframe, background='white', text='asdasdasdasdasd', anchor=W, justify=LEFT, bd=1, relief='solid').grid(column=1, row=3, sticky=(W,E), columnspan=3, pady=0, ipady=0,padx=0,ipadx=0)
Entry(mainframe, background='white', bd=1, relief='sunken').grid(column=1, row=4, sticky=(W,E), columnspan=3, pady=0, ipady=0, padx=0,ipadx=0)
root.mainloop()
Now:
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()
My program creates different widgets depending on the selection from a radio button. Everything works great except I can't seem to clear the old widget if the other radio button is selected. The suggestion here: (https://stackoverflow.com/a/15995920/3924118) isn't working. Here's the relevant code.
From the main program:
root = Tk()
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)
secondframe = ttk.Frame(mainframe)
secondframe.grid(column=4, row=3)
secondframe.columnconfigure(0, weight=1)
secondframe.columnconfigure(0, weight=1)
And then the function:
def pct_from_duration():
""" Calculate needed pct from target duration"""
tgt_dur_entry = ttk.Entry(mainframe, width=4, textvariable=tgt_dur_inp)
tgt_dur_entry.grid(column=5, row=3, sticky=(W, E))
for widget in secondframe.winfo_children():
widget.destroy()
ttk.Label(secondframe, textvariable=pct_bond_end).grid(column=1, row=1)
ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=5, row=4, sticky=W)
FWIW, I get no error message, it just doesn't actually delete the widgets. This is all python 3.6.
Maybe this will help...I'ts an example of your function and it is working(Python 3.5)
import tkinter as tk
from tkinter import *
from tkinter import ttk
class GUI:
def __init__(self, master):
def pct_from_duration():
tgt_dur_entry = ttk.Entry(mainframe, width=4)
tgt_dur_entry.grid(column=5, row=3, sticky=(W, E))
for widget in secondframe.winfo_children():
widget.destroy()
l3 = ttk.Label(secondframe, text = 'Label').grid(column=1, row=1)
b2 = ttk.Button(mainframe, text="Calculate").grid(column=5, row=4, sticky=W)
self.master = master
mainframe = ttk.Frame(master)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
secondframe = ttk.Frame(mainframe)
secondframe.grid(column=4, row=3)
secondframe.columnconfigure(0, weight=1)
secondframe.columnconfigure(0, weight=1)
l = Label(secondframe, text = 'Child_mainframe')
l.grid()
l2 = Label(mainframe, text = 'Child_secondframe')
l2.grid()
r1 = Radiobutton(master, text="Radiobutton", value=1, command = pct_from_duration).grid()
root = Tk()
root.rowconfigure(0, weight = 1)
root.columnconfigure(1, weight=1)
root.columnconfigure(0, weight=1)
root.columnconfigure(0, weight=2)
my_gui = GUI(root)
root.mainloop()
I am trying to create a series of two pop of windows where the first will determine the number of coordinates the user will input and the second will allow the user to input this exact number of coordinates.
My code for the first pop up works and looks like this:
root = Tk()
root.title("User Inputs")
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)
numofcoord = StringVar()
numofcoord = ttk.Entry(mainframe, width=7, textvariable=numofcoord)
numofcoord.grid(column=2, row=1, sticky=(W, E))
ttk.Button(mainframe, text="OK", command=user_coordinates).grid(column=1, row=2, sticky=W)
ttk.Button(mainframe, text="CANCEL", command=quit).grid(column=2, row=2, sticky=W)
ttk.Label(mainframe, text="Number of Coordinates").grid(column=1, row=1, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
root.mainloop()
The first section works, but in the second section, my pop up looks like this where the number of rows is determined by the input in the first pop up window.
http://i.imgur.com/dToI2qX.png
the code for the second section looks like this:
try:
noc = int(numofcoord.get())
root = Tk()
root.title("User Defined Coordinates")
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)
x = StringVar()
y = StringVar()
ttk.Label(mainframe, text="X").grid(column=1, row=1, sticky=(W, E))
ttk.Label(mainframe, text="Y").grid(column=2, row=1, sticky=(W, E))
for i in range(2, noc + 2):
xcoord = ttk.Entry(mainframe, width=7, textvariable=x)
xcoord.grid(column=1, row=i, sticky=(W, E))
ycoord = ttk.Entry(mainframe, width=7, textvariable=y)
ycoord.grid(column=2, row=i, sticky=(W, E))
ttk.Button(mainframe, text="OK", command=test).grid(column=1, row=noc + 3, sticky=W)
ttk.Button(mainframe, text="CANCEL", command=quit).grid(column=2, row=noc + 3, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
root.mainloop()
except ValueError:
pass
The issue is that in when you put a value in either the X or Y column, every box in that column is filled with that value and I would like for each row to be a set of coordinates.
The problem is that all of your entry widgets share the same StringVar. You need to create a new instance of StringVar for each entry widget. Though, you don't really need to use StringVar at all. All you really need to do is keep a reference to each entry widget.
For example:
x_entries = []
y_entries = []
for i in range(2, noc + 2):
xcoord = ttk.Entry(mainframe, width=7)
xcoord.grid(column=1, row=i, sticky=(W, E))
ycoord = ttk.Entry(mainframe, width=7)
ycoord.grid(column=2, row=i, sticky=(W, E))
x_entries.append(xcoord)
y_entries.append(ycoord)
Later, you can get the values like this:
print("first pair: ", x_entries[0].get(), y_entries[0].get())
You can do the same thing by using StringVar, but in most cases that adds complexity by giving you more objects to manage but without giving any real benefit.
Here's an example:
x_vars = []
y_vars = []
for i in range(2, noc + 2):
x = StringVar()
y = StringVar()
xcoord = ttk.Entry(mainframe, width=7, textvariable=x)
xcoord.grid(column=1, row=i, sticky=(W, E))
ycoord = ttk.Entry(mainframe, width=7, textvariable=y)
ycoord.grid(column=2, row=i, sticky=(W, E))
x_vars.append(x)
y_vars.append(y)
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.