Flow Layout с customtkinter добавляет дополнительные отступы между виджетами.Python

Программы на Python
Ответить
Anonymous
 Flow Layout с customtkinter добавляет дополнительные отступы между виджетами.

Сообщение Anonymous »

Я пытаюсь реализовать потоковый макет в ScrollableFrame из customtkinter.
В частности, вместо управления буквами макет должен управлять небольшими фреймами, в которых написаны имена.
Я должен иметь в виду, что размер имен и, следовательно, ширина маленьких фреймов могут различаться. По этой причине использование Grid(), как обычно рекомендуется, не подходило, и я предпочел использовать место для большей точности.
Основная проблема, с которой я столкнулся, заключается в том, что, хотя это не указано, между виджетами добавляются отступы и похоже, что это связано с размером последнего виджета. Это означает, что если последний виджет был большим из-за длинного имени, расстояние между ним и следующим виджетом также будет большим. Это странно, поскольку функция, которую я использую, устанавливает одинаковое постоянное заполнение между всеми виджетами.
Более того, тот факт, что наблюдается дополнительное заполнение, также, по-видимому, делает недействительными вычисления функции макета (do_layout в следующем примере). Это означает, что пока функция «думает», что в строке еще осталось место для другого виджета, дополнительное заполнение не учитывается. Последний виджет строки также виден лишь частично или не виден вообще.
Вот упрощенная версия моего скрипта (она все еще немного длинная из-за необходимых функций/классов):

Код: Выделить всё

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 problem 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()
Вот изображение полученного результата, иллюстрирующее проблему, с которой я столкнулся:
Изображение

На рисунке мы видим, что пространство между «LoooongName» и «Name» намного больше, чем между «Name» и «Name». «ДругоеИмя». Это не предусмотрено, поскольку заполнение self.padx в сценарии является постоянным.
Вот также изображение результата, который я получаю, когда масштабирую окно, чтобы уменьшить его ширину:
Изображение

Здесь мы видим, что последний виджет первой строки («OtherName») еще не был перенесен на вторую строку, хотя он больше почти не виден. Как сказано выше, я предполагаю, что это связано с тем, что функция do_layout не учитывает это неожиданное заполнение между виджетами и предполагает, что в строке еще осталось место. Однако это также может быть другая и несвязанная проблема.
Я пытался проверить, отличается ли ширина внутреннего холста ScrollableFrame от ширины FlowFrame, но это не так. Я также пытался проверить, есть ли разница между «self.winfo_width» и «self.winfo_reqwidth» PersonFrame, но и этого не произошло (хотя я должен признать, что не совсем понимаю разницу между ними).
Заранее благодарю вас за любую помощь или предложения!

Подробнее здесь: https://stackoverflow.com/questions/798 ... en-widgets
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»