Tkinter, alignment - the endless question - python

Since some days I'll try to align these two items inside a Tkinter frame:
The pink part should be on the left and the green button on the right. With HtmlDivs and CSS a question of seconds, with TKinter a pain in the ...
Here is my python code:
import tkinter as tk
root = tk.Tk()
root.geometry("400x200")
buttons = tk.Frame(root)
buttons.pack(side="top", expand=True, fill='both')
label = tk.Label(buttons, text="Hello, world", anchor='w', background='pink')
b2 = tk.Button(buttons, text="EXIT", background='green')
label.grid(row=0, column=1, sticky='w', ipadx = '20', padx = '20')
b2.grid(row=0, column=3, sticky='e', ipadx = '20', padx = '20')
root.mainloop()
The final app will be running fullscreen on a 7" touch display.

The simplest solution is to use pack instead of grid, since you only have a single row of widgets inside of buttons. pack's strength is arranging things in a single row or a single column.
Just remove these two lines:
label.grid(row=0, column=1, sticky='w', ipadx = '20', padx = '20')
b2.grid(row=0, column=3, sticky='e', ipadx = '20', padx = '20')
... and replace them with this:
label.pack(side='left')
b2.pack(side='right')
Also, since you appear to be creating a toolbar, you want to leave expand as False and set fill to just "x", otherwise the toolbar will expand to fill the entire window:
buttons.pack(side="top", expand=False, fill='x')

Thx for your tips,
this is just a testcode to update my maincode.
Its not good to mix .pack and .grid, right ? If i do, the script crashes completely,
so ill have to re-do my mainscript i think.
This is what i need:
row: 1/2: label (it will be a real time clock) left 2/2: exit button (exit fullscreen) right
row: 1/3: image (weather), 2/3: weather data (label), 3/3: calendar
row: 4 buttons: 1. lightoff 2. light25%, 3.light50% 4.light100&
Thats it basically all is working, it just need to align it (im a coding hero g)
Since i have the frame from the code above, i thought i can easily add 2. & 3. row with another frames, but that does not seem to work ??
Preview:
https://i.stack.imgur.com/KzoqV.png
My (main)Code so far
root = Tk()
root.title('Model Definition')
root.config(background = "deepskyblue4")
root.attributes('-fullscreen',True)
root.bind('<Escape>',lambda e: root.destroy())
def currenttime():
string = strftime("%A, %d.%B.%Y %H:%M:%S")
lbl.config(text = string, background = 'deepskyblue4', fg='white', font=("colibri", 30))
lbl.after(1000, currenttime)
def light400():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 401'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light425():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 425'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light450():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 450'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light475():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 500'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
# Main frames
top_frame = Frame(root, bg='deepskyblue4', width=450, height=90, pady=3)
center = Frame(root, bg='deepskyblue2', width=50, height=40, padx=3, pady=3)
btm_frame = Frame(root, bg='deepskyblue4', width=450, height=20, pady=3)
btm_frame2 = Frame(root, bg='deepskyblue4', width=450, height=60, pady=3)
# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
top_frame.grid(row=0, sticky="e", padx=(10, 0))
center.grid(row=1, sticky="nsew", pady=(10, 50))
btm_frame.grid(row=3, sticky="ew")
btm_frame2.grid(row=4, sticky="ew", padx=(10, 50))
# create the widgets for the top frame
lbl = Label(top_frame, background = 'deepskyblue4', anchor=W, justify=LEFT)
lbl.pack()
currenttime()
actionbutton = Button(top_frame, text="X", width=5, height=2, bg="deepskyblue4", fg="white", command=root.destroy)
hdr_left = Frame(top_frame, bg='deepskyblue4', width=100, height=190)
hdr_right = Frame(top_frame, bg='deepskyblue4', width=400, height=190, padx=3, pady=3)
# layout the widgets in the top frame
lbl.grid(row=0, column=1, sticky="w")
actionbutton.grid(row=0, column=2, sticky="e")
# create the center widgets
center.grid_rowconfigure(0, weight=1)
center.grid_columnconfigure(1, weight=1)
ctr_left = Frame(center, bg='deepskyblue2', width=100, height=190)
ctr_mid = Frame(center, bg='deepskyblue2', width=150, height=190, padx=3, pady=3)
ctr_right = Frame(center, bg='deepskyblue2', width=400, height=190, padx=3, pady=3)
ctr_left.grid(row=0, column=0, sticky="ns")
ctr_mid.grid(row=0, column=1, sticky="nsew")
ctr_right.grid(row=0, column=2, sticky="ns")
path = "icons/rain.png"
img = ImageTk.PhotoImage(Image.open(path))
panel = Label(ctr_left, image = img, bg="deepskyblue2")
panel.grid(row=0, columnspan=3)
#imgag = panel.pack(top_frame)
#CENTER ctr_mid
if x["cod"] != "404":
y = x["main"]
y2 = x["wind"]
currenttemp = y["temp"]
currentpressure = y["pressure"]
currenthumidiy = y["humidity"]
z = x["weather"]
weather_description = z[0]["description"]
currentwind = y2["speed"]
label1 = Label(ctr_mid,text='Karlsruhe', font = ('calibri', 30), background = 'deepskyblue2')
label2 = Label(ctr_mid,text='Temperatur: '+str(round(currenttemp-272.15))+' °C', font = ('calibri', 20), background = 'deepskyblue2')
label3 = Label(ctr_mid,text='Beschreibung: '+str(weather_description),font = ('calibri', 20), background = 'deepskyblue2')
label4 = Label(ctr_mid,text='Druck: '+str(currentpressure)+' hPa', font = ('calibri', 20), background = 'deepskyblue2')
label5 = Label(ctr_mid,text='Feuchtigkeit: '+str(currenthumidiy)+' %',font = ('calibri', 20), background = 'deepskyblue2')
label6 = Label(ctr_mid,text='Wind: '+str(currentwind)+' m/Sek',font = ('calibri', 20), background = 'deepskyblue2')
label1.grid(row=0, column=0, sticky="nw")
label2.grid(row=1, column=0, sticky="nw")
label3.grid(row=2, column=0, sticky="nw")
label4.grid(row=3, column=0, sticky="nw")
label5.grid(row=4, column=0, sticky="nw")
label6.grid(row=5, column=0, sticky="nw")
# btm_frame2 widgets
licht = Label(btm_frame2, text='Licht:', width=5, height=1, bg="deepskyblue4", fg='white', font=("colibri", 20))
button = Button(btm_frame2, command=light400, text="AUS", width=5, height=1, bg="deepskyblue2", fg="white")
button2 = Button(btm_frame2, text="25 %", command=light425, width=5, height=1, bg="deepskyblue2", fg="white")
button3 = Button(btm_frame2, text="50%", command=light450, width=5, height=1, bg="deepskyblue2", fg="white")
button4 = Button(btm_frame2, text="100%", command=light475, width=5, height=1, bg="deepskyblue2", fg="white")
licht.grid(row=0, column=0, sticky="nw")
button.grid(row=0, column=1, sticky="nw")
button2.grid(row=0, column=2, sticky="nw")
button3.grid(row=0, column=3, sticky="nw")
button4.grid(row=0, column=4, sticky="nw")
actionbutton.grid(row=0, column=6, sticky="nw")
root.mainloop()

Related

Lower monitor resolution causes tkinter window to be cut at right

I am using Tkinter gui, and at my default screen resolution (1920x1080), the dashboard displays fine as in image:
But when I run the same code on a lower resolution laptop (let's say 1366x768), right most widgets are cut as seen in picture below:
Here is my code which involves 2 windows root_tk is the main window which have a button called dashboard. When we press dashboard button, the dashboard window pops up. I have already tried the solutions Resolution problem of widgets with fixed lengths in Tkinter application
Why is my tkinter Gui cut off on the right?
But they do not work for me. Here is my code:
root_tk = customtkinter.CTk()
root_tk.state("zoomed")
root_tk.rowconfigure(3, weight=1)
root_tk.title("CustomTkinter Test")
frame_0 = Frame(root_tk,background="white")
frame_0.grid(row=0,column=0,sticky="ns",rowspan=4)
def dash():
dash_tk2 = customtkinter.CTkToplevel(root_tk)
dash_tk2.state("zoomed")
dash_tk2.update_idletasks()
dash_tk2.title("Dashboard")
dash_tk2.configure(bg='#302E2E')
frame_dash1 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
frame_dash2 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
frame_dash2a = customtkinter.CTkFrame(master=frame_dash2, corner_radius=15, fg_color="#FBBDBE")
frame_dash3 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
frame_dash3a = customtkinter.CTkFrame(master=frame_dash3, corner_radius=15, fg_color="#FBBDBE")
frame_dash4 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
frame_dash4a = customtkinter.CTkFrame(master=frame_dash4, corner_radius=15, fg_color="#FBBDBE")
frame_dash5 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
frame_dash5a = customtkinter.CTkFrame(master=frame_dash5, corner_radius=15, fg_color="#FBBDBE")
frame_dash6 = customtkinter.CTkFrame(master=dash_tk2, corner_radius=15, fg_color="white")
blank_row1 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", height=10)
blank_col1 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_col2 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_col3 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_col4 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_col5 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_col6 = customtkinter.CTkFrame(master=dash_tk2, fg_color="yellow", width=10)
blank_row1.grid(row=0, column=0,columnspan=6)
blank_col1.grid(row=1, column=0)
frame_dash1.grid(row=1, column=1, sticky='ns',rowspan=2)
blank_col2.grid(row=1, column=2)
frame_dash2.grid(row=1, column=3, sticky='n',rowspan=2)
blank_col3.grid(row=1, column=4)
frame_dash3.grid(row=1, column=5, sticky='n',rowspan=2)
blank_col4.grid(row=1, column=6)
frame_dash4.grid(row=1, column=7, sticky='n',rowspan=2)
blank_col5.grid(row=1, column=8)
frame_dash5.grid(row=1, column=9, sticky='n',rowspan=2)
blank_col6.grid(row=1, column=10)
frame_dash6.grid(row=1, column=11, sticky='n')
frame_dash2a.grid(row=1, column=1, pady=(20, 10))
frame_dash3a.grid(row=1, column=1, pady=(20, 10))
frame_dash4a.grid(row=1, column=1, pady=(20, 10))
frame_dash5a.grid(row=1, column=1, pady=(20, 10))
blank_row2 = customtkinter.CTkFrame(master=frame_dash1, fg_color="orange", height=15)
blank_row2.grid(row=0,column=0,columnspan=2)
lab_tag = Label(frame_dash1, text="TAG", anchor=W, width=20, font='Tahoma 7', fg="black", bg='white')
lab_tag2 = Label(frame_dash1, text="FLOW Meter 4981", anchor=W, width=20, font='Tahoma 15', fg="black", bg='white')
blank_col7 = customtkinter.CTkFrame(master=frame_dash1, fg_color="orange", width=15)
blank_col7.grid(row=1, column=0,rowspan=15,sticky='ns')
lab_tag.grid(row=2, column=1, pady=(10, 0), sticky='w')
lab_tag2.grid(row=3, column=1, sticky='w')
lab_dashhead2 = Label(frame_dash2, text="MASS FLOW (KG/HR)", anchor=CENTER, font='Tahoma 10 bold', fg="white",bg='#EB3F3F')
lab_massflow2a = Label(frame_dash2a, text="19,999.999", anchor=CENTER, font='Tahoma 25 bold', fg="black", bg='#FBBDBE',width=10)
blank_col8 = customtkinter.CTkFrame(master=frame_dash2, fg_color="orange", width=10)
blank_col8.grid(row=1, column=0,rowspan=3)
blank_col9 = customtkinter.CTkFrame(master=frame_dash2, fg_color="orange", width=10)
blank_col9.grid(row=1, column=2,rowspan=3)
lab_dashhead2.grid(row=0, column=0, sticky='ew', pady=15, ipady=5, columnspan=3)
lab_massflow2a.grid(row=0, column=0, pady=20)
lab_dashhead3 = Label(frame_dash3, text="VOLUMETRIC FLOW (M\u00b3/HR)", anchor=CENTER, font='Tahoma 10 bold', fg="white",bg='#EB3F3F')
lab_massflow3a = Label(frame_dash3a, text="99,999", anchor=CENTER, font='Tahoma 25 bold', fg="black", bg='#FBBDBE',width=10)
blank_col10 = customtkinter.CTkFrame(master=frame_dash3, fg_color="orange", width=10)
blank_col10.grid(row=1, column=0,rowspan=3)
blank_col11 = customtkinter.CTkFrame(master=frame_dash3, fg_color="orange", width=10)
blank_col11.grid(row=1, column=2,rowspan=3)
lab_dashhead3.grid(row=0, column=0, sticky='ew', pady=15, ipady=5, columnspan=3)
lab_massflow3a.grid(row=0, column=0, pady=20)
lab_dashhead4 = Label(frame_dash4, text="STD.VOLUMETRIC FLOW (KG/HR)", anchor=CENTER, font='Tahoma 10 bold',fg="white", bg='#EB3F3F')
lab_massflow4a = Label(frame_dash4a, text="99999.99", anchor=CENTER, font='Tahoma 25 bold', fg="black", bg='#FBBDBE',width=10)
blank_col12 = customtkinter.CTkFrame(master=frame_dash4, fg_color="orange", width=10)
blank_col12.grid(row=1, column=0,rowspan=3)
blank_col13 = customtkinter.CTkFrame(master=frame_dash4, fg_color="orange", width=10)
blank_col13.grid(row=1, column=2,rowspan=3)
lab_dashhead4.grid(row=0, column=0, sticky='ew', pady=15, ipady=5, columnspan=3)
lab_massflow4a.grid(row=0, column=0, pady=20)
lab_dashhead5 = Label(frame_dash5, text="ENERGY FLOW (KG/HR)", anchor=CENTER, font='Tahoma 10 bold', fg="white",
bg='#EB3F3F')
lab_massflow5a = Label(frame_dash5a, text="99999.99", anchor=CENTER, font='Tahoma 25 bold', fg="black", bg='#FBBDBE',width=10)
blank_col14 = customtkinter.CTkFrame(master=frame_dash5, fg_color="orange", width=10)
blank_col14.grid(row=1, column=0,rowspan=3)
blank_col15 = customtkinter.CTkFrame(master=frame_dash5, fg_color="orange", width=10)
blank_col15.grid(row=1, column=2,rowspan=3)
lab_dashhead5.grid(row=0, column=0, sticky='ew', pady=15, ipady=5, columnspan=3)
lab_massflow5a.grid(row=0, column=0, pady=20)
lab_dashhead6a = Label(frame_dash6, text="REAL FACTORS", anchor=CENTER, font='Tahoma 10 bold',fg="white", bg='#7F7F7F',width=34)
lab_diffpx_un = Label(frame_dash6, text="MEASUREMENT FACTORS INVOLVED IN PROCESS (%)", anchor=CENTER,font='Tahoma 10', fg="black", bg='#C0C0C0',wraplength=200)
lab_diffpx_un_val = Label(frame_dash6, text="", anchor=CENTER, font='Tahoma 13 bold', fg="black",bg='#E8E8E8')
lab_dashhead6a.grid(row=0, column=0, sticky='ew', pady=(15,25), ipady=5)
lab_diffpx_un.grid(row=1, column=0, sticky='ew')
lab_diffpx_un_val.grid(row=2, column=0, sticky='ew')
dash_tk2.mainloop()
Good Question! You can actually make a parent frame for all those frames and widgets and add a scrollbar in x axis to that parent frame.. How to insert a scrollbar to a frame
You have to assign a weight to the grid cells you created. If you want every grid cell in row 1 of the top-level to be equally weighted, you do it like the following:
dash_tk2.grid_columnconfigure((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), weight=1)
Small window:
Wide window:

Python TKinter Mac: Buttons layout strangely & click don't work

Python TKinter Mac: Buttons layout strangely and when a button is clicked it looks the same (as if it hadn't been clicked) however I didn't check to see if the button worked.
and the space is a textbook
the Mac version is: a 2017 iMac running Monterey 12.4
import tkinter as tk
window = tk.Tk()
window.geometry("500x500")
window.title("Stock Watchlist & Logger")
label = tk.Label(window, text="Tester", font=('Ariel', 18))
label.pack(padx=20, pady=20)
textbox = tk.Text(window, height=3, font=('Ariel', 16))
textbox.pack(padx=10, pady=10)
numbuttframe = tk.Frame(window)
numbuttframe.columnconfigure(0, weight=1)
yesnobuttframe = tk.Frame(window)
yesnobuttframe.columnconfigure(1, weight=1)
button1 = tk.Button(numbuttframe, text="1", font=('Arial', 18))
button1.grid(row=0, column=0, sticky=tk.W+tk.E)
button2 = tk.Button(numbuttframe, text="2", font=('Arial', 18))
button2.grid(row=0, column=1, sticky=tk.W+tk.E)
button3 = tk.Button(numbuttframe, text="3", font=('Arial', 18))
button3.grid(row=0, column=2, sticky=tk.W+tk.E)
button4 = tk.Button(numbuttframe, text="4", font=('Arial', 18))
button4.grid(row=0, column=3, sticky=tk.W+tk.E)
button5 = tk.Button(numbuttframe, text="5", font=('Arial', 18))
button5.grid(row=0, column=4, sticky=tk.W+tk.E)
button6 = tk.Button(numbuttframe, text="6", font=('Arial', 18))
button6.grid(row=0, column=5, sticky=tk.W+tk.E)
yesbutton = tk.Button(yesnobuttframe, text="Yes", font=('Arial', 18))
yesbutton.grid(row=0, column=0, sticky=tk.W+tk.E)
nobutton = tk.Button(yesnobuttframe, text="No", font=('Arial', 18))
nobutton.grid(row=0, column=1, sticky=tk.W+tk.E)
numbuttframe.pack(fill='x')
yesnobuttframe.pack(fill='x')
if button1:
print("CELEBRATE!")
window.mainloop()
You set the weight to two cells weight=1 , so they expanded, since the rest have a default weight of 0. Since I don’t see your grid - the buttons are placed in frames one after the other, suggest using the pack method. And shortened your code a bit. The buttons won't work yet, because they don't have a command = call. Complex variable names in Python are usually written with an underscore.
import tkinter as tk
FONT = ('Ariel', 18)
window = tk.Tk()
window.geometry("500x500")
window.title("Stock Watchlist & Logger")
lbl = tk.Label(window, text="Tester", font=FONT)
lbl.pack(padx=20, pady=20)
text_box = tk.Text(window, height=3, font=('Ariel', 16))
text_box.pack(padx=10, pady=10)
num_btn = tk.Frame(window)
yes_no_btn = tk.Frame(window)
num_btn.pack(fill='x')
yes_no_btn.pack(fill='x')
buttons = []
for i in range(1, 7):
btn = tk.Button(num_btn, text=f"{i}", font=FONT)
btn.pack(side="left", fill='x', expand=True)
buttons.append(btn)
yes_btn = tk.Button(yes_no_btn, text="Yes", font=FONT)
yes_btn.pack(side="left", fill='x', expand=True)
no_btn = tk.Button(yes_no_btn, text="No", font=FONT)
no_btn.pack(side="left", fill='x', expand=True)
window.mainloop()

layout buttons within frame nested in tkk.Notebook

I can't properly layout buttons within frame nested in tkk.Notebook
In Main.py I create ttk.Notebook and attach mainTab instance
root = tk.Tk()
rootFrame = tk.Frame(root, width=600, height=300)
rootFrame.grid(columnspan=1, rowspan=2)
rootFrame.pack(expand=1, fill="both")
tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, columnspan=1, rowspan=1)
mainTab = ttk.Frame(tabs)
mainTab.grid(columnspan=3, rowspan=6)
tabs.add(mainTab, text="Main")
rootFrame.pack(expand=1, fill="both")
mainPane = MainTab(root,mainTab)
root.mainloop()
in mainTab.py I'm trying to insert buttonFrame and layout two buttons within it
class MainTab:
...
def __init__(self, root, mainTab) -> None:
self.root = root
buttonFrame = tk.Frame(mainTab, bg="white")
buttonFrame.grid(column=0, row=4, columnspan=3, rowspan=1)
self.start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font=BUTTON_FONT, bg="green", fg="white") # , height=1, width=14
self.start_btn.grid(column=0, row=0, columnspan=2)
self.reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font=BUTTON_FONT, bg="green", fg="white") # , height=1, width=1
self.reset_btn.grid(column=2, row=0)
...
As a result start button is not properly placed in the grid
It looks like buttonFrame takes full parent frame width and buttons placed in the middle regardless of their grid settings.
How I can properly layout buttons within buttonFrame?
Here is the requested "minimal reproducible example" which also look not good
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Time Tracker")
root.iconbitmap('./assets/logoTransp4icon24.ico')
rootFrame = tk.Frame(root, width=600, height=300)
rootFrame.grid(columnspan=1, rowspan=2)
rootFrame.pack(expand=1, fill="both")
tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, columnspan=1, rowspan=1)
mainTab = ttk.Frame(tabs)
mainTab.grid(columnspan=3, rowspan=6)
buttonFrame = tk.Frame(mainTab, bg="white")
buttonFrame.grid(column=0, row=4, columnspan=3, rowspan=1)
start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font="Arial", bg="green", fg="white") # , height=1, width=14
start_btn.grid(column=0, row=0, columnspan=2)
reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font="Arial", bg="green", fg="white") # , height=1, width=1
reset_btn.grid(column=2, row=0)
timerDisplay = tk.Label(mainTab, text="00:00:00", font="Arial")
timerDisplay.grid(columnspan=2, column=1, row=4)
tabs.add(mainTab, text="Main")
rootFrame.pack(expand=1, fill="both")
root.mainloop()
buttonFrame occupies column 0 to 2 and timerDisplay occupies column 1 to 2. So timerDisplay overlaps buttonFrame. Removing columnspan=3 in buttonFrame.grid(...) can fix the overlapping issue:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Time Tracker")
root.iconbitmap('./assets/logoTransp4icon24.ico')
rootFrame = tk.Frame(root, width=600, height=300)
#rootFrame.grid(columnspan=1, rowspan=2) # override by below line
rootFrame.pack(expand=1, fill="both")
tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, rowspan=1)
mainTab = ttk.Frame(tabs)
#mainTab.grid(columnspan=3, rowspan=6) # not necessary
buttonFrame = tk.Frame(mainTab, bg="white")
buttonFrame.grid(column=0, row=4, rowspan=1) # removed columnspan=3
start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font="Arial", bg="green", fg="white") # , height=1, width=14
start_btn.grid(column=0, row=0, columnspan=2)
reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font="Arial", bg="green", fg="white") # , height=1, width=1
reset_btn.grid(column=2, row=0)
timerDisplay = tk.Label(mainTab, text="00:00:00", font="Arial")
timerDisplay.grid(columnspan=2, column=1, row=4)
tabs.add(mainTab, text="Main")
#rootFrame.pack(expand=1, fill="both") # already called above
root.mainloop()

How to solve the "bad window path name ".!labelframe.!canvas.!frame" error in tkinter python?

This is my code:
mycanvas = Canvas(self.search_result_frame)
mycanvas.pack(side=LEFT)
yscrollbar = ttk.Scrollbar(self.search_result_frame, orient="vertical", command=mycanvas.yview)
yscrollbar.pack(side=RIGHT, fill=Y)
mycanvas.configure(yscrollcommand=yscrollbar.set)
mycanvas.bind('<Configure>', lambda e: mycanvas.configure(scrollregion = mycanvas.bbox('all')))
self.sample_frame = Frame(mycanvas)
mycanvas.create_window((0,0), window=self.sample_frame, anchor=E)
for widget in self.search_result_frame.winfo_children():
widget.destroy()
if len(matching_bills) > 0:
for bill in matching_bills:
with open(f'{self.bill_folder}//{bill}//data//bill_details.json', 'r') as bill_json_file:
bill_details = json.loads(bill_json_file.read())
customer_name = bill_details["customer_details"][0]
payment_method = bill_details["payment_method"]
date_of_issue = bill_details["date_of_issue"]
date_of_issue = datetime.strptime(date_of_issue, "%d/%m/%Y")
date_of_issue = date_of_issue.strftime("%d %b %Y")
# # -------------------- Search Result Frame Contents
result_frame = Frame(self.sample_frame, bg=self.bg3, bd=5, relief=GROOVE)
result_frame.pack(fill=BOTH, pady=2)
result_billno_lbl = Label(result_frame, text=bill, bg=self.bg1, fg="#FFF", font=self.search_results_font1, padx=22, pady=3)
result_billno_lbl.grid(row=0, column=0, padx=50, pady=8, sticky=W)
billed_to_lbl = Label(result_frame, text=f"Billed To - {customer_name}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_to_lbl.grid(row=0, column=1, padx=80, sticky=W)
billed_type_lbl = Label(result_frame, text=f"Bill Type - {payment_method}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_type_lbl.grid(row=0, column=2, sticky=W)
issued_on_lbl = Label(result_frame, text=f"Issued On - {date_of_issue}", bg=self.bg1, fg="#FFF",
font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
issued_on_lbl.grid(row=0, column=3, padx=80, sticky=W)
view_btn = Button(result_frame, text="View", font="Comicsan 14", bd=2, relief=GROOVE, bg="#000", fg="#FFF", padx=1, command=lambda bill=bill: self.view_bill(bill))
view_btn.grid(row=0, column=4, padx=3, columnspan=2, sticky=W)
elif len(matching_bills) == 0:
for widgets in self.search_result_frame.winfo_children():
widgets.destroy()
no_result_lbl = Label(self.search_result_frame, text=f"No search result found for {bill_cat}", font=self.search_results_font1, bg=self.bg3, fg="#FFF")
no_result_lbl.pack(fill=X)
When I run it, it shows me the bad window path name ".!labelframe.!canvas.!frame error and when I try to do the same thing without object-oriented in tkinter then it works well !

Python Tkinter Not Detecting Correct Screen Resolution to Use for GUI Sizing

I have a very specific issue that I have been trying to sort out for some time now. I am using Python 2.7 in Pycharm on Mac. I am working on a touchscreen GUI to interface with a robot. The issue that I am having is that I am trying to make this GUI look as similar as possible on multiple platforms and on different display sizes as far as button and label sizing goes.
What I tried doing is using python to detect the display resolution and from that, base the elements/widgets sizes as ratios of the resolution. This has worked just fine when using my MacBook Pro Retina 15" with a resolution of 1440x900 as well as a Raspberry Pi with resolution set to 1280x800 however when I attempt to do this on a PC with a resolution of 1920x1080, it somehow detects the height to be 1135 instead of 1080. I have two frames created self.f1 and self.f2 which is placed centered in self.f1 and what is interesting is that in my GUI on Windows, somehow the height of self.f2 is larger than the height of self.f1 which I think may be a part of my issue. Here is the specific code for the GUI portion of my program:
def gui_layout(self):
x_default = .5
y_default = .52
if self.version[1] == "1":
x_off = x_default
y_off = .535
elif self.version[1] == "2":
x_off = x_default
y_off = y_default
else:
x_off = x_default
y_off = y_default
# GUI framework initialization
self.title("Operator Interface - " + self.version)
self.w_0, self.h_0 = self.winfo_screenwidth(), self.winfo_screenheight()
self.geometry("%dx%d+0+0" % (self.w_0, self.h_0))
# self.overrideredirect(True)
self.wm_attributes('-fullscreen', 'True')
self.f1 = tk.Frame(width=self.w_0, height=self.h_0, bg="white")
self.f2 = tk.Frame(bg="black")
self.f1.pack(fill="both", expand=True)
self.f2.place(in_=self.f1, anchor="c", relx=x_off, rely=y_off)
# Create status bar objects
if self.version[1] == "2":
self.state_text = " Status: %s |" % self.status.mission_text
self.state_bar = tk.Label(self.f1, text=self.state_text, bd=1, relief='sunken', anchor='w',
font=("Helvetica", 20))
self.state_bar.pack(side='bottom', fill='x')
else:
pass
self.status_text = " State: %s | Current Mission: %s | Battery: %s" % (
self.status.state_text, "Mission Name", self.status.battery_percentage) + "%" + "(%ss) | Network: %s" % (
self.status.battery_time, "Network Status")
self.status_bar = tk.Label(self.f1, text=self.status_text, bd=1, relief='sunken', anchor='w',
font=("Helvetica", 20))
self.status_bar.pack(side='bottom', fill='x')
self.orig_color = self.status_bar.cget("background")
self.image_0 = Image.open("%s/Images/MIR.bmp" % self.folder_path)
self.photo_0 = ImageTk.PhotoImage(self.image_0)
self.image_0_label = tk.Label(self.f1, image=self.photo_0)
self.image_0_label.image = self.photo_0
self.w = self.w_0 / 70
self.h = self.h_0 / 90
self.w_1 = self.w_0 / 96
self.h_1 = self.h_0 / 450
self.button_1 = tk.Button(self.f2, text="Button 1", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_2 = tk.Button(self.f2, text="Button 2", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_3 = tk.Button(self.f2, text="Button 3", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_4 = tk.Button(self.f2, text="Button 4", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_5 = tk.Button(self.f2, text="Button 5", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_6 = tk.Button(self.f2, text="Button 6", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_7 = tk.Button(self.f2, text="Button 7", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w_1, height=self.h_1)
self.button_8 = tk.Button(self.f2, text="Button 8", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w_1, height=self.h_1)
self.button_9 = tk.Button(self.f2, text="Button 9", command=lambda: self.help(), font=("Helvetica", 20),
width=self.w_1, height=self.h_1)
self.image_0_label.pack(fill='x')
self.button_1.grid(row=2, column=2, padx=20, pady=10)
self.button_2.grid(row=2, column=3, padx=20, pady=10)
self.button_3.grid(row=2, column=4, padx=20, pady=10)
self.button_4.grid(row=3, column=2, padx=20, pady=10)
self.button_5.grid(row=3, column=3, padx=20, pady=10)
self.button_6.grid(row=3, column=4, padx=20, pady=10)
self.button_7.grid(row=4, column=2, padx=20, pady=10)
self.button_8.grid(row=4, column=3, padx=20, pady=10)
self.button_9.grid(row=4, column=4, padx=20, pady=10)
self.button_configure()
Also here are the values that I get when running different resolution retrieving commands on the Pi (1st image) and Windows (2nd image).
If anyone has any suggestions or guidance on how I can make this GUI look like this on any screen size, that would be much appreciated. The window itself will not be resized once booted but I just would like it to go full screen and the buttons to size nicely.
Here, try this:
import tkinter as tk
root = tk.Tk()
# set columns 0, 1 and 2 and rows 0 and 1 to expand to the full possible size
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.columnconfigure(2, weight=1)
root.rowconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
# row zero
btn = tk.Button(root, text="Call")
btn.grid(row=0, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Sawyer")
btn.grid(row=0, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Compressor")
btn.grid(row=0, column=2, sticky='nsew', padx=5, pady=5)
# row one
btn = tk.Button(root, text="Send to Loading Dock")
btn.grid(row=1, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Charging Dock")
btn.grid(row=1, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="MiR is on the Way")
btn.grid(row=1, column=2, sticky='nsew', padx=5, pady=5)
# row two
btn = tk.Button(root, text="Supervisor")
btn.grid(row=2, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Setup")
btn.grid(row=2, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Help")
btn.grid(row=2, column=2, sticky='nsew', padx=5, pady=5)
# row three
state_bar = tk.Label(root, text = " State: %s | Current Mission: %s | Battery: %s")
state_bar.grid(row=3, column=0, columnspan=3)
try:
root.state('zoomed') # windows
except:
root.attributes('-zoomed', True) # linux
root.mainloop()
Resize it and see how tkinter handles sizing everything automatically.

Categories

Resources