Tkinter: пользовательский виджет фрейма переопределяет конфигурацию столбцаPython

Программы на Python
Ответить
Anonymous
 Tkinter: пользовательский виджет фрейма переопределяет конфигурацию столбца

Сообщение Anonymous »

Я пытаюсь создать приложение tkinter из 5 столбцов и 2 строк, содержащее ttk.Treeview в верхней строке (охватывающее все 5 столбцов). Нижняя строка должна содержать ttk.Frame в каждом столбце. Ширина фреймов должна соответствовать ширине столбцов древовидного представления. Я добился такого поведения с помощью специального класса пустого фрейма MyFrameResizable. Однако как только я заполняю пользовательский фрейм () с другими виджетами поведение при изменении размера нарушается.

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

import tkinter as tk
from tkinter import ttk

class MyFrame(ttk.Frame):
def __init__(self, master = None, **kwargs):
super().__init__(master, **kwargs)

self.columnconfigure(0, weight=0)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)

# adding other widgets will destroy resizing behavior
self.button = tk.Button(self)
self.button.grid(column=0, row=0, sticky="nesw")

self.entry = tk.Entry(self)
self.entry.grid(column=1, row=0, sticky="nesw")

class MyFrameResizable(ttk.Frame):
def __init__(self, master = None, **kwargs):
super().__init__(master, **kwargs)

self.columnconfigure(0, weight=0)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)

class ResizableApp:
def __init__(self, root):
self.root = root
self.root.title("Resizable Grid Example")

# Treeview with 5 columns
self.treeview = ttk.Treeview(root, columns=("Col1", "Col2", "Col3", "Col4", "Col5"), show="headings")
for i, col in enumerate(("Col1", "Col2", "Col3", "Col4", "Col5"), start=1):
self.treeview.heading(f"# {i}", text=col)
self.treeview.column(f"# {i}", width=100, anchor="center")  # Initial column widths

self.treeview.grid(row=0, column=0, columnspan=5, sticky="nsew")

# Create bottom row frames with different colors
self.style = ttk.Style()
self.frames = []
colors = ["red", "green", "blue", "yellow", "cyan"]
for i, color in enumerate(colors):
self.style.configure(style_name:=f"Custom{i}.TFrame", background=color)

# change to MyFrame breaks resizing behavior
frame = MyFrameResizable(root, height=10, style=style_name)

frame.grid(row=1, column=i, sticky="nsew")
self.frames.append(frame)

# Configure grid weights for resizing
root.grid_rowconfigure(0, weight=1)  # Treeview row resizes with window
root.grid_rowconfigure(1, weight=1)  # Frame row stays fixed
for i in range(5):
root.grid_columnconfigure(i, weight=1)

# Bind resizing events to update frame widths
self.treeview.bind("", self.update_frame_widths)
self.treeview.bind("", self.update_frame_widths)
self.treeview.bind("", self.update_frame_widths)

def update_frame_widths(self, event=None):
"""Update the widths of frames to match Treeview column widths."""
print("update")
for i, frame in enumerate(self.frames):
col_width = self.treeview.column(f"# {i + 1}", option="width")  # Get current column width
frame.config(width=col_width)

# Run the app
if __name__ == "__main__":
root = tk.Tk()
app = ResizableApp(root)
root.mainloop()
Я ожидал, что менеджер макета сетки назначит ширину фреймам независимо от их содержимого. Я думал, что после определения ширины фрейма дочерние виджеты фрейма будут распределены по сетке в соответствии с доступным пространством.
Однако кажется, что включение дочерних виджетов переопределяет ширину столбца, установленную через конфигурация столбца. Почему это?

Подробнее здесь: https://stackoverflow.com/questions/793 ... nconfigure
Ответить

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

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

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

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

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