tkinter:在画布上使用滚动条

发布于 2024-12-09 03:46:10 字数 760 浏览 0 评论 0原文

我正在尝试使画布可滚动。然而,一旦我尝试设置滚动条来使用画布,tkinter 似乎完全忽略了我最初为画布设置的尺寸。我尝试将它们全部打包在一个框架中,设置画布以填充框架,然后设置框架大小,但这会出现相同的问题,除非我将框架也设置为填充窗口,这不是我想要的。基本上,我想要一个带有滚动条的固定大小的画布。我当前的代码如下所示(在 python 3.1 中):

from tkinter import *
root=Tk()
frame=Frame(root,width=300,height=300)
frame.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
hbar=Scrollbar(canvas,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(canvas,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)

root.mainloop()

I'm trying to make a canvas scrollable. However, once I try to set up scrollbars to work with the canvas, tkinter seems to completely ignore the dimensions I initially set for my canvas. I've tried packing them all in a frame, setting the canvas to fill the frame and then setting the frame size, but that presents the same problem unless I set the frame to fill the window as well, which isn't what I want. Basically, I want a fixed-size canvas with scrollbars on it. My current code looks like this (in python 3.1):

from tkinter import *
root=Tk()
frame=Frame(root,width=300,height=300)
frame.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
hbar=Scrollbar(canvas,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(canvas,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)

root.mainloop()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

层林尽染 2024-12-16 03:46:10

您的滚动条需要将 Frame 作为父级,而不是 Canvas:

from tkinter import *
root=Tk()
frame=Frame(root,width=300,height=300)
frame.pack(expand=True, fill=BOTH) #.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
hbar=Scrollbar(frame,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)

root.mainloop()

其工作原理取决于 pack 的工作原理。默认情况下,它将尝试缩小(或增大)容器以完全适合其子容器。由于在原始示例中滚动条是画布的子级,因此画布会缩小以适应。

如果您希望滚动条出现在画布内,技巧是使用额外的框架。将画布和滚动条放置在此内部框架中,关闭画布的边框并打开框架的边框。将框架的背景设置为与画布相同,就会出现滚动条位于画布内部的情况。

Your scrollbars need to have the Frame as a parent, not the Canvas:

from tkinter import *
root=Tk()
frame=Frame(root,width=300,height=300)
frame.pack(expand=True, fill=BOTH) #.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
hbar=Scrollbar(frame,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)

root.mainloop()

The reason why this works is due to how pack works. By default it will attempt to shrink (or grow) a container to exactly fit its children. Because the scrollbars are children of the canvas in the original example, the canvas shrinks to fit.

If you want the scrollbars to appear inside the canvas, the trick is to use an extra frame. Place the canvas and scrollbars in this inner frame, turn the borders off of the canvas and on for the frame. Set the background of the frame to be the same as the canvas and it will appear that the scrollbars are inside the canvas.

狼亦尘 2024-12-16 03:46:10

滚动条也可以在没有框架的情况下工作,通过在声明滚动条时传递画布而不是框架vbar=Scrollbar(canvas,orient=VERTICAL)

The scrollbar can also work without a frame, by passing canvas instead of frame when declaring your Scrollbar vbar=Scrollbar(canvas,orient=VERTICAL)

愚人国度 2024-12-16 03:46:10

当我使用 .pack 选项时,以下代码有效。但是使用 .place 选项时,它不起作用

from tkinter import ttk
import tkinter as tk



root = tk.Tk()
container = ttk.Frame(root)
container.pack()
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)


x=ttk.Label(scrollable_frame, text="Sample scrolling label")
x.place(x=50,y=50)


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

root.mainloop()

为什么当我使用 .place 时它不起作用?

The following code works, when I use the .pack option. But with the .place option, it is not working

from tkinter import ttk
import tkinter as tk



root = tk.Tk()
container = ttk.Frame(root)
container.pack()
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)


x=ttk.Label(scrollable_frame, text="Sample scrolling label")
x.place(x=50,y=50)


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

root.mainloop()

Why is it not working when I use .place?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文