如何使用 python 3.8 在 tkinter 的 canvas 中创建滚动条
How to create a scrollbar in a canvas in tkinter using python 3.8
我创建了一个 canvas c 并且我想在 canvas 中放置一个滚动条来向下和向上滚动我在 canvas 中放置的所有内容(我是打算放很多东西)。但是滚动条不起作用。我做错了什么?
from tkinter import *
root = Tk()
c=Canvas(root)
c.config(width=160,height=100)
c.grid(row=0,column=0)
Scrb=Scrollbar(root,orient=VERTICAL)
Scrb.grid(column=2)
c.config(scrollregion=c.bbox("all"))
c.config(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)
label = Label(c, text="this is to fill room")
label1 = Label(c, text="this is to fill room")
label2 = Label(c, text="this is to fill room")
label3 = Label(c, text="this is to fill room")
label4 = Label(c, text="this is to fill room")
label5 = Label(c, text="this is to fill room")
label6 = Label(c, text="this is to fill room")
list_labels = [label,label1,label2,label3,label4,label5,label6]
for i in range(0,7):
list_labels[i].grid(row=i,column=0)
root.mainloop()
这里有一些问题。首先,标签不是 canvas 项目,它们是它们自己的小部件,您正在网格化到根目录中。 (虽然您确实将 canvas 作为它们的父级,但这不起作用,但由于 canvas 的工作方式,它实际上只是将其传递给根而不是错误——这会很好,但这是有原因的。)
接下来,您用第一个标签(其中 i=0)覆盖了放置 canvas 的 0, 0 网格,因此 canvas 甚至不显示。
接下来,您将滚动条放在第 2 列并跳过第 1 列。这没有任何问题(也许您稍后会在第 1 列中放一些东西,谁知道呢,)我只是想确保您知道那里发生了什么。
您真正需要弄清楚的是,如果您想要滚动 canvas 或滚动一些小部件(如标签、按钮等)。如果真的想要滚动 canvas,请使用看看 http://effbot.org/zone/tkinter-scrollbar-patterns.htm#canvas
为了您的方便,如果您只是想复制和粘贴,我已经从那里包含了一个片段(在 canvas 上添加了一些元素,所以您可以真正看到滚动):
from tkinter import *
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, scrollregion=(0, 0, 1000, 1000),
xscrollcommand=xscrollbar.set,
yscrollcommand=yscrollbar.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)
for i in range(100):
canvas.create_rectangle(
i/10*100, i%10*100, i/10*100+50, i%10*100+50,
fill='green')
frame.pack()
如果你真的只是想要一个滚动区域,你可以在其中放置任何你想要的小部件,网上的人似乎推荐的是滚动 canvas 并在其中放置一个 window ,然后在 window 中添加您的项目。所以你是在正确的轨道上这样做。您还希望 scrollregion 配置在每次移动时都发生,而不是在制作时发生一次。
这是您所拥有内容的修改版本:
from tkinter import *
root = Tk()
frame = Frame(root, width=160, height=100)
c=Canvas(frame)
c.config(width=160,height=100)
c.pack(side=LEFT)
def innerFrameGo(_):
c.configure(scrollregion=c.bbox('all'))
inner_frame = Frame(c)
inner_frame.bind("<Configure>", innerFrameGo)
inner_frame_id = c.create_window(0,0,window=inner_frame,anchor=NW)
Scrb=Scrollbar(frame,orient=VERTICAL)
Scrb.pack(side=RIGHT, fill=Y)
c.configure(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)
frame.pack()
for i in range(0,7):
label = Label(inner_frame, text="this is to fill room")
label.grid(row=i, column=0)
root.mainloop()
P.S。关于您制作的标签列表……如果您一遍又一遍地输入内容,这是一个好兆头,表明有更简单的方法来完成您想要做的事情。无论如何你都会有一个 for-loop,我把那部分移到了那里。
我创建了一个 canvas c 并且我想在 canvas 中放置一个滚动条来向下和向上滚动我在 canvas 中放置的所有内容(我是打算放很多东西)。但是滚动条不起作用。我做错了什么?
from tkinter import *
root = Tk()
c=Canvas(root)
c.config(width=160,height=100)
c.grid(row=0,column=0)
Scrb=Scrollbar(root,orient=VERTICAL)
Scrb.grid(column=2)
c.config(scrollregion=c.bbox("all"))
c.config(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)
label = Label(c, text="this is to fill room")
label1 = Label(c, text="this is to fill room")
label2 = Label(c, text="this is to fill room")
label3 = Label(c, text="this is to fill room")
label4 = Label(c, text="this is to fill room")
label5 = Label(c, text="this is to fill room")
label6 = Label(c, text="this is to fill room")
list_labels = [label,label1,label2,label3,label4,label5,label6]
for i in range(0,7):
list_labels[i].grid(row=i,column=0)
root.mainloop()
这里有一些问题。首先,标签不是 canvas 项目,它们是它们自己的小部件,您正在网格化到根目录中。 (虽然您确实将 canvas 作为它们的父级,但这不起作用,但由于 canvas 的工作方式,它实际上只是将其传递给根而不是错误——这会很好,但这是有原因的。)
接下来,您用第一个标签(其中 i=0)覆盖了放置 canvas 的 0, 0 网格,因此 canvas 甚至不显示。
接下来,您将滚动条放在第 2 列并跳过第 1 列。这没有任何问题(也许您稍后会在第 1 列中放一些东西,谁知道呢,)我只是想确保您知道那里发生了什么。
您真正需要弄清楚的是,如果您想要滚动 canvas 或滚动一些小部件(如标签、按钮等)。如果真的想要滚动 canvas,请使用看看 http://effbot.org/zone/tkinter-scrollbar-patterns.htm#canvas 为了您的方便,如果您只是想复制和粘贴,我已经从那里包含了一个片段(在 canvas 上添加了一些元素,所以您可以真正看到滚动):
from tkinter import *
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, scrollregion=(0, 0, 1000, 1000),
xscrollcommand=xscrollbar.set,
yscrollcommand=yscrollbar.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)
for i in range(100):
canvas.create_rectangle(
i/10*100, i%10*100, i/10*100+50, i%10*100+50,
fill='green')
frame.pack()
如果你真的只是想要一个滚动区域,你可以在其中放置任何你想要的小部件,网上的人似乎推荐的是滚动 canvas 并在其中放置一个 window ,然后在 window 中添加您的项目。所以你是在正确的轨道上这样做。您还希望 scrollregion 配置在每次移动时都发生,而不是在制作时发生一次。 这是您所拥有内容的修改版本:
from tkinter import *
root = Tk()
frame = Frame(root, width=160, height=100)
c=Canvas(frame)
c.config(width=160,height=100)
c.pack(side=LEFT)
def innerFrameGo(_):
c.configure(scrollregion=c.bbox('all'))
inner_frame = Frame(c)
inner_frame.bind("<Configure>", innerFrameGo)
inner_frame_id = c.create_window(0,0,window=inner_frame,anchor=NW)
Scrb=Scrollbar(frame,orient=VERTICAL)
Scrb.pack(side=RIGHT, fill=Y)
c.configure(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)
frame.pack()
for i in range(0,7):
label = Label(inner_frame, text="this is to fill room")
label.grid(row=i, column=0)
root.mainloop()
P.S。关于您制作的标签列表……如果您一遍又一遍地输入内容,这是一个好兆头,表明有更简单的方法来完成您想要做的事情。无论如何你都会有一个 for-loop,我把那部分移到了那里。