Flow Layout mit customtkinter fügt zusätzlichen Abstand zwischen Widgets hinzuPython

Python-Programme
Anonymous
 Flow Layout mit customtkinter fügt zusätzlichen Abstand zwischen Widgets hinzu

Post by Anonymous »

Ich versuche, ein Flow-Layout in einem ScrollableFrame von customtkinter zu implementieren. Anstatt Buchstaben zu verwalten, muss das Layout insbesondere kleine Rahmen verwalten, in denen Namen geschrieben werden. Ich muss bedenken, dass die Größe der Namen und damit die Breite der kleinen Rahmen variieren kann. Aus diesem Grund war die normalerweise empfohlene Verwendung von „grid()“ nicht geeignet, und ich habe für mehr Präzision die Verwendung von „place“ vorgezogen.
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_layout
im folgenden Beispiel). Dies bedeutet, dass die Funktion zwar davon ausgeht, dass in der Zeile noch Platz für ein weiteres Widget vorhanden ist, der zusätzliche Abstand jedoch nicht berücksichtigt wird. Auch das letzte Widget einer Zeile ist nur teilweise oder gar nicht sichtbar.
Hier 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()
Hier ist ein Bild des Ergebnisses, das ich erhalte, das das Problem veranschaulicht, auf das ich stoße:
Image

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:
Image

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.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post