Why are the grids different?
I have this code in a class that generates a frame for each mp3 file in a list. These frames are added to a scrollable frame.
class Playable(CTkFrame):
def __init__(self, master:any, controller:UiController, pm:PlayableMeta):
super().__init__(master)
self.pm = pm
self.controller = controller
self.grid_rowconfigure((0, 1), weight=1)
self.columnconfigure(index=0, weight=1)
self.columnconfigure(index=1, weight=5)
self.columnconfigure(index=2, weight=1)
self.lbl_title = CTkLabel(self,
text=pm.title,
font=("Arial", 28), anchor="nw")
self.lbl_artist = CTkLabel(self,
text=pm.artist,
font=("Arial", 16), anchor="nw")
self.lbl_length = CTkLabel(self,
text="00:00.000",
font=("Arial", 16), bg_color="#228B22", anchor="e", padx=5, pady=5)
self.lbl_start = CTkLabel(self,
text="00:00.000",
font=("Arial", 16), bg_color="#444", text_color="#999", anchor="e", padx=5, pady=5)
if pm.start > 0:
self.lbl_start.configure(bg_color="#FF6347", text_color="white")
PositionStuff.full_sticky_mid_pad(self.lbl_title, row=0, col=1 )
PositionStuff.full_sticky_mid_pad(self.lbl_artist, row=1, col=1)
PositionStuff.full_sticky_mid_pad(self.lbl_length, row=0, col=2 )
PositionStuff.full_sticky_mid_pad(self.lbl_start, row=1, col=2 )
class PositionStuff:
@staticmethod
def full_sticky(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew", padx=10, pady=10)
@staticmethod
def full_sticky_mid_pad(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
@staticmethod
def full_sticky_no_pad(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew")
When I run this code with an example of two mp3 files, the labels and titles are rendered in different positions:
In the bottom frame the title is shifted to the left and the labels are shorter. I am confused, as of why? The text is more or less the same length.
If I add the hint I've found on the Internettz:
self.grid_propagate(False)
This happens:
...which is absolutely not want I expected. Is there a way to enforce the grid to be "fixed" in width and height?
@svenakela Could you please have s sample reproducible code that we can run on our machine?
import customtkinter
from customtkinter import CTkLabel, CTkFrame
from dataclasses import dataclass
@dataclass
class Metadata:
title: str
artist: str
length: str
start: str
class Playable(CTkFrame):
def __init__(self, master:any, metadata:Metadata):
super().__init__(master)
self.grid_rowconfigure((0, 1), weight=1)
self.columnconfigure(index=0, weight=1)
self.columnconfigure(index=1, weight=5)
self.columnconfigure(index=2, weight=1)
self.lbl_title = CTkLabel(self,
text=metadata.title,
font=("Arial", 28), bg_color="Purple", anchor="nw")
self.lbl_artist = CTkLabel(self,
text=metadata.artist,
font=("Arial", 16), anchor="nw")
self.lbl_length = CTkLabel(self,
text=metadata.length,
font=("Arial", 16), bg_color="green", anchor="e", padx=5, pady=5)
self.lbl_start = CTkLabel(self,
text=metadata.start,
font=("Arial", 16), bg_color="#444", text_color="#999", anchor="e", padx=5, pady=5)
self.full_sticky_mid_pad(self.lbl_title, row=0, col=1 )
self.full_sticky_mid_pad(self.lbl_artist, row=1, col=1)
self.full_sticky_mid_pad(self.lbl_length, row=0, col=2 )
self.full_sticky_mid_pad(self.lbl_start, row=1, col=2 )
@staticmethod
def full_sticky_mid_pad(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
def main():
def full_sticky_mid_pad(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
ctk = customtkinter.CTk()
ctk.title("Align Test")
ctk.geometry("1000x400")
ctk.grid_rowconfigure(0, weight=1)
ctk.grid_columnconfigure(0, weight=1)
frame = CTkFrame(master=ctk)
frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=0)
frame.grid_rowconfigure(1, weight=0)
frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
# First frame
m1 = Metadata(title = "Yadee ho hoo", artist = "Mr Bonkers", length = "04:31.003", start = "00:00.000")
p1 = Playable(frame, m1)
p1.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
# Second frame
m1 = Metadata(title = "Balvinore/Dumbledore", artist = "In da getto", length = "03:21.015", start = "00:51.000")
p1 = Playable(frame, m1)
p1.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
ctk.mainloop()
if __name__ == "__main__":
main()
Updates:
- I think the first element should be placed on (0, 0).
- Set proper weightage for each cell.
- Use
fg_colorinstead ofbg_colorso that you can use radius also. - You can use internal padding to beautify your text.
Revised version of your code:
import customtkinter
from customtkinter import CTkLabel, CTkFrame
from dataclasses import dataclass
@dataclass
class Metadata:
title: str
artist: str
length: str
start: str
class Playable(CTkFrame):
def __init__(self, master:any, metadata:Metadata):
super().__init__(master)
self.grid_rowconfigure((0, 1, 2, 3), weight=1)
self.grid_columnconfigure(0, weight=1)
self.lbl_title = CTkLabel(self, corner_radius=5,
text=metadata.title, padx=10, # Use internal padding for text.
font=("Arial", 28), fg_color="Purple", anchor="nw")
self.lbl_artist = CTkLabel(self, padx=10,
text=metadata.artist,
font=("Arial", 16), anchor="nw")
self.lbl_length = CTkLabel(self, corner_radius=5,
text=metadata.length,
font=("Arial", 16), fg_color="green", anchor="e", padx=20, pady=5)
self.lbl_start = CTkLabel(self, corner_radius=5,
text=metadata.start,
font=("Arial", 16), bg_color="#444", text_color="#999", anchor="e", padx=20, pady=5)
self.full_sticky_mid_pad(self.lbl_title, row=0, col=0)
self.full_sticky_mid_pad(self.lbl_artist, row=1, col=0)
self.full_sticky_mid_pad(self.lbl_length, row=0, col=1)
self.full_sticky_mid_pad(self.lbl_start, row=1, col=1)
@staticmethod
def full_sticky_mid_pad(panel, row=0, col=0, padding: tuple = (5, 5)):
return panel.grid(row=row, column=col, sticky="nsew", padx=padding[0], pady=padding[1])
def main():
def full_sticky_mid_pad(panel, row=0, col=0):
return panel.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
ctk = customtkinter.CTk()
ctk.title("Align Test")
ctk.geometry("1000x400")
ctk.grid_rowconfigure(0, weight=1)
ctk.grid_columnconfigure(0, weight=1)
frame = CTkFrame(master=ctk)
frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=0)
frame.grid_rowconfigure(1, weight=0)
frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
# First frame
m1 = Metadata(title = "Yadee ho hoo", artist = "Mr Bonkers", length = "04:31.003", start = "00:00.000")
p1 = Playable(frame, m1)
p1.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
# Second frame
m2 = Metadata(title = "Balvinore/Dumbledore", artist = "In da getto", length = "03:21.015", start = "00:51.000")
p2 = Playable(frame, m2)
p2.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
ctk.mainloop()
if __name__ == "__main__":
main()
Output:
Wait what, this doesn't make sense at all. Even though I agree with your statement Set proper weightage for each cell, it is contradicted by the code you provided.
You are setting cell weight for four rows and one column:
self.grid_rowconfigure((0, 1, 2, 3), weight=1)
self.grid_columnconfigure(0, weight=1)
But later the code is using two rows and two columns:
self.full_sticky_mid_pad(self.lbl_title, row=0, col=0)
self.full_sticky_mid_pad(self.lbl_artist, row=1, col=0)
self.full_sticky_mid_pad(self.lbl_length, row=0, col=1)
self.full_sticky_mid_pad(self.lbl_start, row=1, col=1)
In my example code the 0 column is empty on purpose. It is later propagated with icons but it doesn't help to describe the alignment problem. 😃
Use the 'uniform' property
Unfortunately the UI became too slow with all the UI objects. The project has migrated to Qt.