the Label Frame is getting wider that I don't - python-3.x

I am using python 3.11.0a5. How do I get actually LabelFrame to draw actually size in column 1? Unfortunately, I can't figure out to work around columnspan, rowspan, etc Here is pics
Unfortunately, I don't want the LabelFrame to draw wider. Here is pics.
Here is code:
from tkinter import *
from tkinter import ttk
#Create an instance of tkinter frame
win= Tk()
#Define the geometry of the window
win.geometry("400x160")
lblChannelName = ttk.Label(win, text='Channel Name')
lblChannelName.grid(row=0, column=0, sticky='W')
entry_channelname = ttk.Entry(win, width=45)
entry_channelname.grid(row=0, column=1, sticky='W')
lblChannelTopic = ttk.Label(win, text = 'Channel Topic')
lblChannelTopic.grid(row=1, column=0, pady=2, sticky='W')
entry_channelTopic = ttk.Entry(win, width=45)
entry_channelTopic.grid(row=1, column=1, pady=2, sticky='W')
#Initialize a LabelFrame Widget
labelframe = LabelFrame(win, width=400, height=200, bd=5)
labelframe.grid(row=3, padx=2, pady=5, columnspan=18, sticky='WE')
#Checkbutton Invite
invite = IntVar()
ck1 = ttk.Checkbutton(labelframe, text ='Invite Only[+i]', variable=invite)
ck1.grid(row=0, column=0, padx=0, sticky='W')
#Checkbutton Moderated
moderated = IntVar()
ck2 = ttk.Checkbutton(labelframe, text ='Moderated[+m]', variable=moderated)
ck2.grid(row=0, padx=170, columnspan=3, sticky='W')
#Checkbutton Message
message = IntVar()
ck3 = ttk.Checkbutton(labelframe, text ='No Outside Message[+n]', variable=message)
ck3.grid(row=1, column=0, sticky='W')
#Checkbutton Private
private = IntVar()
ck4 = ttk.Checkbutton(labelframe, text ='Private[+p]', variable=private)
ck4.grid(row=1, padx=170, columnspan=3, sticky='W')
#Checkbutton Only ops
topics = IntVar()
ck5 = ttk.Checkbutton(labelframe, text ='Only ops set topics[+t]', variable=topics)
ck5.grid(row=2, column=0, sticky='W')
#Checkbutton Secret Channel
secret = IntVar()
ck6 = ttk.Checkbutton(labelframe, text ='Secret Channel[+s]', variable=secret)
ck6.grid(row=2, padx=170, columnspan=3, sticky='W')
#Checkbutton Keyed
keyed = IntVar()
ck7 = ttk.Checkbutton(labelframe, text ='Channel is keyed[+k]', variable=keyed)
ck7.grid(row=3, column=0, sticky='W')
lblkeyed = ttk.Label(labelframe, text='Key:')
lblkeyed.grid(row=3, padx=135, columnspan=2, sticky='W')
entry_keyed = ttk.Entry(labelframe, width=20)
entry_keyed.grid(row=3, padx=170, columnspan=3, sticky='W')
#Checkbutton limit
limit = IntVar()
ck8 = ttk.Checkbutton(labelframe, text ='Limit channel members[+l]', variable=limit)
ck8.grid(row=4, column=0, sticky='W')
win.mainloop()
How can I fix the Labe Frame in pics 1?
I appreciate your help.

In your code, when you grid labelframe, change the columnspan to 2. Line 24 will look like this:
labelframe.grid(row=3, padx=2, pady=5, columnspan=2, sticky='WE')
That will set your LabelFrame to the right width.
If you want the entries to align with the LabelFrame, you can make them sticky='WE'. Lines 14 and 20 would look like this:
# Line 14
entry_channelname.grid(row=0, column=1, sticky='WE')
# Line 20
entry_channelTopic.grid(row=1, column=1, pady=2, sticky='WE')

Related

Python/tkinter - change entry status via checkbox

I want to activate the second entry when the checkbox is checked...but the it works the other way around. What am I doing wrong? Based on another question I have posted it seems the event "<ButtonRelease>" occurs before the bonding. Why is that? Can I use "command" in the checkbox instaed?
import tkinter as tk
def set_entry_status(event, var, widg):
print(var.get())
if var.get():
widg[-1]['state'] = 'normal'
else:
widg[-1]['state'] = 'disabled'
def CustomWidget(frame, name, unit, ):
var_e = []
widget_e = []
var_c = tk.IntVar(master=frame, value=0)
widget_c = tk.Checkbutton(master=frame, text='', variable=var_c)
widget_c.grid(row=0, column=0, columnspan=1, padx=5, pady=5, sticky="ns")
label_l = name + " (" + unit + ")" # nome + unità di misura in parentesi per GUI
widget_l = tk.Label(frame, text=label_l, padx=1, pady=1)
widget_l.grid(row=0, column=1, columnspan=1, padx=5, pady=5, sticky="wns")
var_e.append(tk.StringVar(master=frame, value='A'))
widget_e.append(tk.Entry(frame, textvariable=var_e[-1], width=10, state="normal"))
widget_e[-1].grid(row=0, column=2, columnspan=1, padx=5, pady=5, sticky="ns")
var_e.append(tk.StringVar(master=frame, value='B'))
widget_e.append(tk.Entry(frame, textvariable=var_e[-1], width=10, state="normal"))
widget_e[-1].grid(row=0, column=3, columnspan=1, padx=5, pady=5, sticky="ns")
# set initial entry state
if var_c.get():
widget_e[-1]['state'] = 'normal'
else:
widget_e[-1]['state'] = 'disabled'
# checkbox - binding
widget_c.bind("<ButtonRelease>", lambda event: set_entry_status(event, var_c, widget_e))
root = tk.Tk()
root.title('My Window')
CustomWidget(root, 'name', 'unit')
root.mainloop()
Indeed you can use command kwarg like I suggested in my other answer. In that case event must be removed from the arguments of your callback function:
import tkinter as tk
def set_entry_status(var, widg):
print(var.get())
if var.get():
widg[-1]['state'] = 'normal'
else:
widg[-1]['state'] = 'disabled'
def CustomWidget(frame, name, unit, ):
var_e = []
widget_e = []
var_c = tk.IntVar(master=frame, value=0)
widget_c = tk.Checkbutton(master=frame, text='', variable=var_c, command=lambda: set_entry_status(var_c, widget_e))
widget_c.grid(row=0, column=0, columnspan=1, padx=5, pady=5, sticky="ns")
label_l = name + " (" + unit + ")" # nome + unità di misura in parentesi per GUI
widget_l = tk.Label(frame, text=label_l, padx=1, pady=1)
widget_l.grid(row=0, column=1, columnspan=1, padx=5, pady=5, sticky="wns")
var_e.append(tk.StringVar(master=frame, value='A'))
widget_e.append(tk.Entry(frame, textvariable=var_e[-1], width=10, state="normal"))
widget_e[-1].grid(row=0, column=2, columnspan=1, padx=5, pady=5, sticky="ns")
var_e.append(tk.StringVar(master=frame, value='B'))
widget_e.append(tk.Entry(frame, textvariable=var_e[-1], width=10, state="normal"))
widget_e[-1].grid(row=0, column=3, columnspan=1, padx=5, pady=5, sticky="ns")
# set initial entry state
if var_c.get():
widget_e[-1]['state'] = 'normal'
else:
widget_e[-1]['state'] = 'disabled'
root = tk.Tk()
root.title('My Window')
CustomWidget(root, 'name', 'unit')
root.mainloop()

Why is the tkinter text widget screwing up my cell sizes?

All was going well as seen in the 1st pic below. all the cells are the same perfect size. its great.
But then comes the implementation of the textbox. and all hell breaks loose. as seen in the 2nd picture it completely disrupts my grid layout. i dont want the textbox adjusting cell sizes, i want it to go where i tell it to go like all the other widgets do. Ive spent hours on this and no avail!
import tkinter as tk
from tkinter import ttk, scrolledtext
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
for i in range(0,20):
for x in range(0,20):
root.columnconfigure(i, weight=1)
root.rowconfigure(x, weight=1)
for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
for x in range(0, 20):
tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)
main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")
frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")
for i in range(2, 5): # start at 2 and end after the 3rd loop.
for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)
frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)
frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)
tab1 = ttk.Frame(root)
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')
# width and height does indeed adjust the texbox size but the textbox still isnt properly sticking to the grid that i set.
frame3_tab_panel_tab1 = tk.Text(root, relief="ridge", bd=2, undo=True, wrap="none", background='#1E1E1E', insertbackground='white')#, width=40, height=10)
frame3_tab_panel_tab1.grid(column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5)
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
root.mainloop()
"""
text_area = scrolledtext.ScrolledText(tab1, wrap = tk.WORD, width=40, height=10, font=("Times New Roman", 15))
text_area.grid(column = 0, pady = 10, padx = 10)
text_area.focus()
"""
without textbox. as you can see its all perfectly even.
FYI: this is just a template im working on so i can better understand tk's positioning.
textbox ruining grid by not adjusting itself accordingly and fitting to the grid i set.
There is a lot of wrong doing in your code and you really should take a good tutorial for tkinter and you may wish to have a brief overview of tkinters geometry management.
The biggest issue is whats causes your code to work differently as you expect it, you always define the root as the master. Every widget, except for the root window, has a master and is set by the ONLY positional argument every widget requiers. Note that if None is given, the root window is set by default. This is, because tkinter is built hirachically and at the top of this hirachy stands the root window (the instance of tk.Tk()).
A master should be a container and this means either the root window, a Toplevel or a Frame. Masters can have so called children, which can be every other widget plus frames that are handled as children. The relationship between a master and a frame are various, but for the scope of this question we will just look at the geometry.
Every widget has a geometry and can be received by the universal widget method .winfo_geometry() that will give you a geometry string 'widthxheight±x_offset±y_offset' (e.g. '120x50-0+20'). The geometry string is the basement for every calculations to order your widgets, which you can affect by choosing a geometry manager and different optional keywords. With those information an output will be created and displayed on your screen.
Suggestion:
import tkinter as tk
from tkinter import ttk, scrolledtext
def populate_frame_1():
frame_1_label = tk.Label(frame_1,text='User Panel',
background = 'black',
foreground = 'white')
frame_1_label.grid(column=0,row=0,sticky='ew',columnspan=3)
frame_1.columnconfigure(0,weight=1)
frame_1.columnconfigure(1,weight=1)
frame_1.columnconfigure(2,weight=1)
for i in range(0, 3):
for x in range(1, 16):
l = tk.Button(frame_1, text=f"Button-{(x-2)}",
bg="white", fg="black")
l.grid(column=i, row=x, sticky="EW", padx=5, pady=5)
def populate_frame_2():
frame_2_label = tk.Label(frame_2,text='Editor',
background = 'black',
foreground = 'white')
textbox = tk.Text(frame_2,width=35)
listbox = tk.Listbox(frame_2,bg='yellow')
frame_2_label.grid(column=0,row=0,sticky='ew',columnspan=6)
textbox.grid(column=0,row=1,sticky='ns',columnspan=4)
listbox.grid(column=4,row=1,sticky='ns',columnspan=2)
frame_2.rowconfigure(1,weight=2)
def populate_frame_3():
frame_3_label = tk.Label(frame_3,text='Info Panel',
background = 'black',
foreground = 'white')
frame_3_label.grid(column=0,row=0,sticky='ew',columnspan=5)
control_panel = ttk.Notebook(frame_3)
tab1 = ttk.Frame(control_panel)
tab2 = ttk.Frame(control_panel)
tab3 = ttk.Frame(control_panel)
control_panel.add(tab1, text ='Generic Editor')
control_panel.add(tab2, text ='Text Compare')
control_panel.add(tab3, text ='Script Ref')
control_panel.grid(column=0,row=1,sticky='nswe')
frame3_tab_panel_tab1 = tk.Text(tab1, relief="ridge", bd=2, undo=True,
wrap="none", background='#1E1E1E',
insertbackground='white',width=40, height=10)
frame3_tab_panel_tab1.pack(fill=tk.BOTH,expand=True)
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
frame_3.rowconfigure(1,weight=2)
frame_3.columnconfigure(0,weight=2)
XOFFSET = 75
YOFFSET = 50
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
main_frame = tk.Frame(root,background='blue')
frame_1 = tk.Frame(main_frame,background='red')
frame_2 = tk.Frame(main_frame,background='green')
frame_3 = tk.Frame(main_frame,background='red')
main_frame.pack(fill=tk.BOTH,expand=True,
padx=XOFFSET,pady=YOFFSET)
frame_1.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)
frame_2.pack(side=tk.LEFT,fill=tk.Y,pady=YOFFSET,expand=True)
frame_3.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)
populate_frame_1()
populate_frame_2()
populate_frame_3()
root.mainloop()
Change
frame3_tab_panel_tab1.grid(
column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5
)
to
frame3_tab_panel_tab1.grid(
column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5,
sticky="NSEW"
)
I managed to solve it by replacing the Text() widget with the scrolledtext.ScrolledText() widget. Its strange. No grid was required and if i remove height and width then it messes it up. Why does height and width have such an impact? why does it even exist when you have things like column and row configure along with sticky. Tkinter is quite confusing sometimes with its logic. But anyways, got there in the end.
Here's the code in case anyone encounters a similar issue.
import tkinter as tk
from tkinter import ttk, scrolledtext
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
for i in range(0,20):
for x in range(0,20):
root.columnconfigure(i, weight=1)
root.rowconfigure(x, weight=1)
for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
for x in range(0, 20):
tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)
main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")
frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")
for i in range(2, 5): # start at 2 and end after the 3rd loop.
for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)
frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)
frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel_tab1 = scrolledtext.ScrolledText(root, bd=2, undo=True, wrap="none", width=40, height=10, font=("Times New Roman", 15), background='#1E1E1E', insertbackground='white')
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(frame3_tab_panel_tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')
root.mainloop()

Why do my ttk.Checkbuttons display blocked out by default?

Good day.
I am attempting to create an options selection menu for a school assignment.
I am using the Python 3.7.2 Themed Tkinter library in order to display this program properly. However, I am having some issues getting my ttk.Checkbutton() widgets to display appropriately. However, while the Checkbutton() is set to be unchecked by default, it is displaying a black square within the button. I have confirmed that this black square represents a false value, as when I click it it displays the true check. When I uncheck it, however, it becomes blank rather than returning to the black square state.
I have checked this issue with both BooleanVar() and IntVar() values, with the same issue.
Here is an excerpt from the code, which is functional:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("Order Manager")
menu__pizza_1_count = IntVar()
menu__pizza_1_count.set(0)
menu__pizza_1_cheese = BooleanVar()
menu__pizza_1_cheese.set(False)
menu__pizza_1_bacon = BooleanVar()
menu__pizza_1_bacon.set(False)
menu__pizza_1_label = ttk.Label(root, text="A Shrubbery")
menu__pizza_1_label.grid(row=0, column=0, columnspan=2, padx=5, pady=5)
menu__pizza_1_price = ttk.Label(root, text="$8.50")
menu__pizza_1_price.grid(row=1, column=0, columnspan=1, padx=5, pady=5)
menu__pizza_1_current = ttk.Label(root, textvariable=menu__pizza_1_count)
menu__pizza_1_current.grid(row=1, column=1, padx=5, pady=5)
menu__pizza_1_cheese = ttk.Checkbutton(root, text="Cheese", variable=menu__pizza_1_cheese, offvalue=False, onvalue=True)
menu__pizza_1_cheese.grid(row=2, column=0, pady=5)
menu__pizza_1_bacon = ttk.Checkbutton(root, text="Bacon", variable=menu__pizza_1_bacon, offvalue=False, onvalue=True)
menu__pizza_1_bacon.grid(row=2, column=1, pady=5)
menu__pizza_1_increase = ttk.Button(root, width=7, text="+") #add count COMMAND
menu__pizza_1_increase.grid(row=3, column=0, padx=5, pady=5)
menu__pizza_1_decrease = ttk.Button(root, width=7, text="-") #decrease count COMMAND
menu__pizza_1_decrease.grid(row=3, column=1, padx=5, pady=5)
[This is what the end result looks like on my end][1]
Does anyone have any suggestions on how to get it do display as blank by default?
Regards,
Elliott
[1]: https://i.stack.imgur.com/DfzMT.png
You checkbox name in the same as the variable name. If you use different names, the checkboxes work correctly.
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("Order Manager")
vmenu__pizza_1_count = IntVar()
vmenu__pizza_1_count.set(0)
vmenu__pizza_1_cheese = BooleanVar()
vmenu__pizza_1_cheese.set(False)
vmenu__pizza_1_bacon = BooleanVar()
vmenu__pizza_1_bacon.set(False)
menu__pizza_1_label = ttk.Label(root, text="A Shrubbery")
menu__pizza_1_label.grid(row=0, column=0, columnspan=2, padx=5, pady=5)
menu__pizza_1_price = ttk.Label(root, text="$8.50")
menu__pizza_1_price.grid(row=1, column=0, columnspan=1, padx=5, pady=5)
menu__pizza_1_current = ttk.Label(root, textvariable=vmenu__pizza_1_count)
menu__pizza_1_current.grid(row=1, column=1, padx=5, pady=5)
menu__pizza_1_cheese = ttk.Checkbutton(root, text="Cheese", variable=vmenu__pizza_1_cheese, offvalue=False, onvalue=True)
menu__pizza_1_cheese.grid(row=2, column=0, pady=5)
menu__pizza_1_bacon = ttk.Checkbutton(root, text="Bacon", variable=vmenu__pizza_1_bacon, offvalue=False, onvalue=True)
menu__pizza_1_bacon.grid(row=2, column=1, pady=5)
menu__pizza_1_increase = ttk.Button(root, width=7, text="+") #add count COMMAND
menu__pizza_1_increase.grid(row=3, column=0, padx=5, pady=5)
menu__pizza_1_decrease = ttk.Button(root, width=7, text="-") #decrease count COMMAND
menu__pizza_1_decrease.grid(row=3, column=1, padx=5, pady=5)
root.mainloop()
Startup Output

How to reposition widgets in tkinter without disturbing adjacent widgets?

I have a button in column 5, and have several Labels at column 1, 2, 3 and 4 (each at row 0). When I use pady for my button in column 5 , other labels also come down making it harder to achieve the desired layout.
I don't know of any other way of repositioning widgets in the y-direction except pady.
Code
from tkinter import *
from tkinter import ttk
root = Tk()
root.geometry("1000x500")
root.title("Stock Manager")
root.resizable(False, False)
Label(root, text="Image", font=20).grid(column=0, row=0, pady=5, padx=50)
Label(root, text="Product No.", font=20).grid(column=1, row=0, pady=5, padx=40)
prodnumempty = Label(root, text="00547", font=16).grid(column=1, row=1)
Label(root, text="Description", font=20).grid(column=2, row=0, pady=5, padx=40)
Label(root, text="Quantity", font=20).grid(column=3, row=0, pady=5, padx=40)
Label(root, text="Price", font=20).grid(column=4, row=0, pady=5, padx=40)
historybtn = ttk.Button(root, text="See Product History").grid(column=5, row=0)
root.mainloop()
I want the See Product History button to be at the bottom while other labels should remain fixed at their position.
One approach is to have all the labels in a frame, gridded on the left, and the button gridded on th eright, in a lower row:
Something like this:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("1000x500")
root.title("Stock Manager")
root.resizable(False, False)
left_frame = tk.Frame(root, width=900, height=500)
tk.Label(left_frame, text="Image", font=20).grid(column=0, row=0, pady=5, padx=50)
tk.Label(left_frame, text="Product No.", font=20).grid(column=1, row=0, pady=5, padx=40)
prodnumempty = tk.Label(left_frame, text="00547", font=16).grid(column=1, row=1)
tk.Label(left_frame, text="Description", font=20).grid(column=2, row=0, pady=5, padx=40)
tk.Label(left_frame, text="Quantity", font=20).grid(column=3, row=0, pady=5, padx=40)
tk.Label(left_frame, text="Price", font=20).grid(column=4, row=0, pady=5, padx=40)
left_frame.grid(column=2, row=0)
historybtn = ttk.Button(root, text="See Product History").grid(column=5, row=1)
root.mainloop()

How Can I write Python code for Temperature Convert to C orF using Frames, Entry Box and Label?

from tkinter import*
def convert2c():
try:
f = float(tempIN.get())
c = (f-32)*5.0/9.0
tempOUTc.set(c)
except ValueError:
pass
def convert2f():
try:
c = float(tempIN.get())
f = c*9.0/5.0 + 32
tempOUTf.set(f)
except ValueError:
pass
root = Tk()
f = root
root.title("Temperature Converter")
root.geometry('{}x{}'.format(500,200))
topFrm = Frame(root, width=500, height=80, bg="#e01111")
midFrm = Frame(root, width=500, height=150, bg="#795fb5")
btmFrm = Frame(root, width=500, height=100)
btmL = Frame(btmFrm, width=250, height=100, bg="#4117a5")
btmR = Frame(btmFrm, width=250, height=100, bg="#3f454f")
topFrm.grid(row=0, sticky="W")
midFrm.grid(row=1)
btmFrm.grid(row=3)
btmL.grid(row=2, column=0)
btmR.grid(row=2, column=2)
tempIN = StringVar()
tempOUTc = StringVar()
tempOUTf = StringVar()
Label(f, text="Temperature Converter\n A number in temperature degree is converted into another as one of the button is clicked").grid(column=0, row=0)
Label(f, text="Enter a Temperature").grid(column=0, row=1)
Entry(f, textvariable=tempIN, width=10) .grid(column=0, rowspan=1, row=1, sticky=W)
Button(f, text=" to Celsius", command=convert2c) .grid(column=0, row=3, sticky=W)
Button(f, text=" to Fahrenheit", command=convert2f) .grid(column=1, row=3, sticky=W)
Label(f, textvariable=tempOUTc) .grid(column=2, row=1, sticky=W)
Label(f, textvariable=tempOUTf) .grid(column=2, row=2, sticky=W)
root.mainloop()

Resources