Das Hauptproblem, auf das ich gestoßen bin, besteht darin, dass zwischen den Widgets ein Abstand hinzugefügt wird, obwohl dieser nicht angegeben ist, und dieser scheinbar mit der Größe des letzten Widgets zusammenhängt. Das heißt, wenn das letzte Widget aufgrund eines langen Namens groß war, wird auch der Abstand zwischen ihm und dem nächsten Widget groß sein. Das ist seltsam, weil die von mir verwendete Funktion den gleichen konstanten Abstand zwischen allen Widgets festlegt.
Darüber hinaus scheint die Tatsache, dass zusätzlicher Abstand sichtbar ist, auch die Berechnungen der Layoutfunktion ungültig zu machen (
Code: Select all
do_layoutHier ist eine vereinfachte Version meines Skripts:
Code: Select all
import customtkinter as ctk
class PersonFrame(ctk.CTkFrame):
# (I need to keep it as a Frame for future implementations)
""" Frame that shows the name of the Registered Person """
def __init__(self, master, name):
super().__init__(master, fg_color="#444455", corner_radius=8)
ctk.CTkLabel(self, text=name).pack(padx=10, pady=6)
class FlowFrame(ctk.CTkFrame):
""" Frame responsible of the flow layout """
def __init__(self, master, padx=0, pady=0):
# The [url=viewtopic.php?t=26065]problem[/url] persists even with paddings of 0
super().__init__(master)
self.padx = padx
self.pady = pady
self.widgets = []
# Binding the function 'do_layout' to the scaling of the Frame
self.bind("", self.do_layout)
def add_widget(self, widget):
self.widgets.append(widget)
widget.place(in_=self)
def do_layout(self, event=None):
""" Calculates the height that the Frame should have
and moves children widgets accordingly to a flow layout """
max_width = self.winfo_width()
if max_width max_width:
x = self.padx
y += row_height + self.pady
row_height = 0
# place() is required here to manually implement a flow layout
# (pack and grid are not suitable)
widget.place(x=x, y=y)
x += w + self.padx
row_height = max(row_height, h)
self.configure(height=y + row_height + self.pady)
class RegisteredFrame(ctk.CTkScrollableFrame):
""" Main display Frame containing the FlowFrame """
def __init__(self, master):
super().__init__(master)
self.flow = FlowFrame(self)
self.flow.pack(fill="x", expand=True)
for name in (
"LooooooooooooooongNaaaaame",
"Name",
"OtherName",
"OtherVeryLongName",
):
self.flow.add_widget(PersonFrame(self.flow, name))
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.geometry("600x400")
self.title("Flow layout spacing issue")
RegisteredFrame(self).pack(fill="both", expand=True)
if __name__ == "__main__":
App().mainloop()

Auf dem Bild können wir sehen, dass der Abstand zwischen „LoooongName“ und „Name“ viel größer ist als zwischen „Name“ und „OtherName“. Was nicht beabsichtigt ist, da die Auffüllung „self.padx“ im Skript konstant ist.
Hier ist auch ein Bild des Ergebnisses, das ich erhalte, wenn ich das Fenster skaliere, um seine Breite zu verringern:

Hier sehen wir, dass das letzte Widget der ersten Zeile ('OtherName') noch nicht in die zweite Zeile verschoben wurde, obwohl es fast nicht mehr sichtbar ist. Wie oben erwähnt, vermute ich, dass dies daran liegt, dass die Funktion do_layout diesen unerwarteten Abstand zwischen den Widgets nicht berücksichtigt und davon ausgeht, dass in der Zeile noch Platz vorhanden ist. Dies könnte jedoch auch ein anderes und nicht zusammenhängendes Problem sein.
Ich habe versucht zu überprüfen, ob die Breite des internen Canvas des ScrollableFrame von der Breite des FlowFrame abweicht, aber das war nicht der Fall. Ich habe auch versucht zu überprüfen, ob es einen Unterschied zwischen self.winfo_width und self.winfo_reqwidth des PersonFrame gibt, aber auch das war nicht der Fall.
Mobile version