如何在 canvas 中滚动多个帧?

How can I scroll multiple frames in canvas?

我想创建一个框架列表,其中包含按钮、标签等更多功能。但我的问题是 LabelFrame 的大小。如果我将 LabelFrame 放在容器中,它就像我想要的那样适合,但它不再可滚动。有什么想法吗?

from tkinter import ttk
import tkinter as tk 

root = tk.Tk()
container = ttk.Frame(root)
canvas = tk.Canvas(container)
scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)

scrollable_frame.bind(
    "<Configure>",
    lambda e: canvas.configure(
        scrollregion=canvas.bbox("all")
    )
)

canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")

canvas.configure(yscrollcommand=scrollbar.set)


for i in range(50):
    lf = ttk.Frame(scrollable_frame, text=i).grid(column=1, row=i)

    frame_ip = tk.LabelFrame(lf, bg="white", text=i)
    frame_ip.place(relwidth=0.95, relheight=0.2, relx=0.025, rely=0)
    button_scroll1 = tk.Button(frame_ip, text="Start", bg="grey")
    button_scroll1.place(relwidth=0.15, relx=0.025, relheight=0.15, rely=0.1)

container.pack()
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")

root.mainloop()

这是您更新后的代码,其中 ButtonCanvasScrollbar 插入到每个带有网格管理器的 LabelFrame 中。

我还使用行|列配置使 container 可调整大小。

似乎工作正常。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.rowconfigure(0, weight = 1)
root.columnconfigure(0, weight = 1)

root.geometry("341x448")

container = ttk.Frame(root)
container.rowconfigure(0, weight = 1)
container.columnconfigure(0, weight = 1)

canvas = tk.Canvas(container)
scrollbar = ttk.Scrollbar(container, orient = tk.VERTICAL, command = canvas.yview)
scrollable_frame = ttk.Frame(canvas)

scrollable_frame.bind(
    "<Configure>",
    lambda e: canvas.configure(
        scrollregion=canvas.bbox("all")))

canvas.create_window((0, 0), window = scrollable_frame, anchor = tk.NW)

canvas.configure(yscrollcommand = scrollbar.set)

for i in range(15):
    L = ttk.LabelFrame(scrollable_frame, text = "Sample scrolling label")
    L.grid(row = i, column = 0, sticky = tk.NSEW)

    B = ttk.Button( L, text = f"Button {i}")
    B.grid(row = 0, column = 0, sticky = tk.NW)
    K = tk.Canvas(
        L, width = 300, height = 100,
        scrollregion = "0 0 400 400", background = "#ffffff")
    K.grid(row = 1, column = 0, sticky = tk.NSEW)
    S = ttk.Scrollbar( L, command = K.yview)
    S.grid(column = 1, row = 1, sticky = tk.NSEW)
    K["yscrollcommand"] = S.set

container.grid(row = 0, column = 0, sticky = tk.NSEW)
canvas.grid(row = 0, column = 0, sticky = tk.NSEW)
scrollbar.grid(row = 0, column = 1, sticky = tk.NS)
root.mainloop()