Tkinter 可滚动和可扩展的 PanedWindow
Tkinter Scrollable and expandable PanedWindow
我已经在 Whosebug 上搜索了很多,还有很多博客、文档...但我没有找到使“PanedWindow”可滚动和展开 + 填充的方法。
检查这个例子
"""Test"""
# pylint: disable=unused-wildcard-import,wildcard-import
from tkinter import Canvas, Scrollbar, Tk, Wm
from tkinter.constants import BOTH, CENTER, HORIZONTAL, LEFT, NSEW, X
from tkinter.ttk import Button, Frame, Label, PanedWindow, Style
STYLE = {
"TButton": {
"configure": {
"background": "#333333",
"foreground": "white",
"padding": 8,
"relief": "flat",
"border": 2,
},
"map": {
"background": [("active", "#777777")],
"foreground": [("active", "white")],
},
},
}
class ScrollableFrame(Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
scrollbar = Scrollbar(self, orient="vertical")
scrollbar.pack(side="right", fill="y")
canvas = Canvas(self, borderwidth=2, background="red")
canvas.pack(side=LEFT, fill=BOTH, expand=True)
canvas.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=canvas.yview)
frame = Frame(canvas, style="DEBUG.TFrame")
canvas.create_window((0, 0), window=frame, anchor=CENTER)
# COMMENT THIS, and the paned is scrollable, but frame does NOT expand
# frame.pack(expand=1, fill=BOTH)
frame.bind("<Configure>", self.on_configure)
self.scollbar = scrollbar
self.canvas = canvas
self.frame = frame
def on_configure(self, event):
self.canvas.configure(
scrollregion=self.canvas.bbox("all"),
)
def create_right_pane(master):
frame = Frame(master)
label = Label(frame, text="This is a cool text")
label.pack()
return frame
def create_left_pane(master):
frame = ScrollableFrame(master)
title = Label(frame.frame, text="Hello !!!")
title.pack(expand=True, fill=BOTH, anchor=CENTER)
for i in range(100):
Button(frame.frame, text=f"Channel {i} ❱").pack(expand=True, fill=BOTH)
return frame
app = Tk(className="MyApp")
style = Style()
style.theme_create("app", None, STYLE)
style.theme_use("app")
app.title("MyApp")
app.geometry("1120x550")
splitpane = PanedWindow(app, orient=HORIZONTAL)
splitpane.pack(expand=True, fill=BOTH)
leftframe = create_left_pane(splitpane)
rightframe = create_right_pane(splitpane)
splitpane.add(leftframe, weight=1)
splitpane.add(rightframe, weight=5)
app.mainloop()
ScrollableFrame中有评论class
评论 frame.pack() => 它滚动,但内容未展开且未填充 X
取消注释 frame.pack() => 现在内容填充 space,但它不可滚动
我想做的只是让内容“填充space”并且“可滚动”。
如果您发现问题,并且可以修复它(或提供解决方案)...谢谢!
默认情况下,内框会根据其内容展开或缩小到最佳大小。由于框架的内容不如 canvas 宽,因此框架不会像 canvas.
宽。
如果你想让它填充 canvas,你需要在 canvas 改变大小时明确设置宽度与 canvas 的宽度相同。
首先,让我们确保我们可以通过给它一个标签来识别内部框架。您可以轻松捕获 window_create
.
返回的标识符
canvas.create_window((0, 0), window=frame, anchor=CENTER, tags=("inner_frame",))
接下来,添加绑定以在 canvas 配置更改时调用函数。
canvas.bind("<Configure>", self.resize_inner_frame)
最后,定义resize函数。在 <Configure>
事件中,event
对象将包含一个 width
参数,代表对象的宽度。我们可以用它来确定内框的宽度。
def resize_inner_frame(self, event):
self.canvas.itemconfigure("inner_frame", width=event.width)
您可能需要调整宽度以适应 canvas 边框。
我已经在 Whosebug 上搜索了很多,还有很多博客、文档...但我没有找到使“PanedWindow”可滚动和展开 + 填充的方法。
检查这个例子
"""Test"""
# pylint: disable=unused-wildcard-import,wildcard-import
from tkinter import Canvas, Scrollbar, Tk, Wm
from tkinter.constants import BOTH, CENTER, HORIZONTAL, LEFT, NSEW, X
from tkinter.ttk import Button, Frame, Label, PanedWindow, Style
STYLE = {
"TButton": {
"configure": {
"background": "#333333",
"foreground": "white",
"padding": 8,
"relief": "flat",
"border": 2,
},
"map": {
"background": [("active", "#777777")],
"foreground": [("active", "white")],
},
},
}
class ScrollableFrame(Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
scrollbar = Scrollbar(self, orient="vertical")
scrollbar.pack(side="right", fill="y")
canvas = Canvas(self, borderwidth=2, background="red")
canvas.pack(side=LEFT, fill=BOTH, expand=True)
canvas.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=canvas.yview)
frame = Frame(canvas, style="DEBUG.TFrame")
canvas.create_window((0, 0), window=frame, anchor=CENTER)
# COMMENT THIS, and the paned is scrollable, but frame does NOT expand
# frame.pack(expand=1, fill=BOTH)
frame.bind("<Configure>", self.on_configure)
self.scollbar = scrollbar
self.canvas = canvas
self.frame = frame
def on_configure(self, event):
self.canvas.configure(
scrollregion=self.canvas.bbox("all"),
)
def create_right_pane(master):
frame = Frame(master)
label = Label(frame, text="This is a cool text")
label.pack()
return frame
def create_left_pane(master):
frame = ScrollableFrame(master)
title = Label(frame.frame, text="Hello !!!")
title.pack(expand=True, fill=BOTH, anchor=CENTER)
for i in range(100):
Button(frame.frame, text=f"Channel {i} ❱").pack(expand=True, fill=BOTH)
return frame
app = Tk(className="MyApp")
style = Style()
style.theme_create("app", None, STYLE)
style.theme_use("app")
app.title("MyApp")
app.geometry("1120x550")
splitpane = PanedWindow(app, orient=HORIZONTAL)
splitpane.pack(expand=True, fill=BOTH)
leftframe = create_left_pane(splitpane)
rightframe = create_right_pane(splitpane)
splitpane.add(leftframe, weight=1)
splitpane.add(rightframe, weight=5)
app.mainloop()
ScrollableFrame中有评论class
评论 frame.pack() => 它滚动,但内容未展开且未填充 X
取消注释 frame.pack() => 现在内容填充 space,但它不可滚动
我想做的只是让内容“填充space”并且“可滚动”。
如果您发现问题,并且可以修复它(或提供解决方案)...谢谢!
默认情况下,内框会根据其内容展开或缩小到最佳大小。由于框架的内容不如 canvas 宽,因此框架不会像 canvas.
宽。如果你想让它填充 canvas,你需要在 canvas 改变大小时明确设置宽度与 canvas 的宽度相同。
首先,让我们确保我们可以通过给它一个标签来识别内部框架。您可以轻松捕获 window_create
.
canvas.create_window((0, 0), window=frame, anchor=CENTER, tags=("inner_frame",))
接下来,添加绑定以在 canvas 配置更改时调用函数。
canvas.bind("<Configure>", self.resize_inner_frame)
最后,定义resize函数。在 <Configure>
事件中,event
对象将包含一个 width
参数,代表对象的宽度。我们可以用它来确定内框的宽度。
def resize_inner_frame(self, event):
self.canvas.itemconfigure("inner_frame", width=event.width)
您可能需要调整宽度以适应 canvas 边框。