【问题标题】:How to create a scrollbar in a canvas in tkinter using python 3.8如何使用 python 3.8 在 tkinter 的画布中创建滚动条
【发布时间】:2020-09-03 18:25:34
【问题描述】:

我创建了一个画布 c,我想在画布中放置一个滚动条来向下和向上滚动我放在画布中的所有东西(我打算放很多东西)。但是滚动条不起作用。我做错了什么?

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()

【问题讨论】:

  • 您需要将 tkinter 窗口对象作为参数添加到 Scrollbar() 方法中,而不是您的画布对象:Scrb=Scrollbar(root,orient=VERTICAL)
  • 谢谢@Max,现在看起来好多了,但还是不行。以及如何连接滚动条来滚动画布?

标签: python python-3.x tkinter canvas scrollbar


【解决方案1】:

这里有一些问题。首先,标签不是画布项目,它们是您自己网格化到根的小部件。 (虽然您确实将画布作为其父级,但这是行不通的,但由于画布的工作方式,它实际上只是将其传递给根而不是出错——这很好,但这是有原因的方式。)

接下来,您使用第一个标签(其中 i=0)覆盖了放置画布的 0、0 网格,因此画布甚至不显示。

接下来,您将滚动条放在第 2 列并跳过了第 1 列。这没有什么问题(也许您稍后会在第 1 列中放一些东西,谁知道呢)我只是想确保您知道什么正在那里发生。

您真正需要弄清楚的是,如果您想要滚动画布或滚动一些小部件(如标签、按钮等)。如果真的想要滚动画布,请查看 http://effbot.org/zone/tkinter-scrollbar-patterns.htm#canvas 为了您的方便,如果您只想复制和粘贴,我已经从那里添加了一个 sn-p(在画布上添加了一些元素,因此您可以真正看到滚动):

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()

如果您实际上只是想要一个滚动区域,您可以在其中放置您想要的任何小部件,那么网上人们似乎建议使用滚动画布并在其中放置一个窗口,然后在该窗口中添加您的项目。所以你在正确的轨道上做那件事。您还希望滚动区域配置在每次移动时都发生,而不仅仅是在制作时发生一次。 这是您所拥有的修改后的版本:

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()

附:关于您制作的标签列表...如果您一遍又一遍地输入内容,这是一个好兆头,表明有一种更简单的方法可以做您想做的事情。因为无论如何你都会有一个 for 循环,所以我把那部分移到了那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2014-06-04
    • 2011-12-05
    • 2018-05-02
    • 1970-01-01
    • 2015-03-16
    相关资源
    最近更新 更多