Tkinter画布和滚动条

4

我发现了一些与这个问题相关的问题和答案,但是没有一个解决方案让我理解为什么这段代码不起作用:

root=tk.Tk()

vscrollbar = tk.Scrollbar(root)

c= tk.Canvas(root,background = "#D2D2D2",yscrollcommand=vscrollbar.set)

vscrollbar.config(command=c.yview)
vscrollbar.pack(side=tk.LEFT, fill=tk.Y) 

f=tk.Frame(c) #Create the frame which will hold the widgets

c.pack(side="left", fill="both", expand=True)
c.create_window(0,0,window=f)

testcontentA = tk.Label(f,wraplength=350 ,text=r"Det er en kendsgerning, at man bliver distraheret af læsbart indhold på en side, når man betragter dens websider, som stadig er på udviklingsstadiet. Der har været et utal af websider, som stadig er på udviklingsstadiet. Der har været et utal af variationer, som er opstået enten på grund af fejl og andre gange med vilje (som blandt andet et resultat af humor).")
testcontentB = tk.Button(f,text="anytext")
testcontentA.pack()
testcontentB.pack()

f.pack()

c.config(scrollregion=c.bbox("all"))

root.mainloop()

我有一个tkinter窗口,其中包含动态生成的内容 - 这意味着如果屏幕上要显示的小部件太多,则需要能够向下滚动。我希望能够使用小部件填充框架“f”,然后使用canvas.create_window()函数以可滚动的方式显示它。

目前窗口已显示,但滚动条未启用 - 就像scrollregion不正确或滚动条与画布之间的链接不正确一样。

3个回答

7
如果您要在画布中嵌入一个框架,则必须使用 create_window,而不是 pack。第一步是删除 f.pack()
其次,在 tkinter 有机会显示小部件之后,需要设置 bbox,因为只有在它们实际上在屏幕上绘制出来之后,它们的大小才能被计算出来。
完成这一点的简单方法是在调用 c.config(scrollregion=c.bbox("all")) 之前调用 root.update(),或者使用 after_idle 安排运行该命令。
您代码中的另一个错误(我猜是...)是您在 (0,0) 处创建窗口,但未设置锚点。这意味着当我猜测您希望左上角位于 (0,0) 时,内部框架将居中显示。
将您的 create_window 调用更改为以下内容:
c.create_window(0,0,window=f, anchor='nw')

太好了 - 非常感谢!我会测试一下并回来。 - user3535074

4
import tkinter as tk

root=tk.Tk()

vscrollbar = tk.Scrollbar(root)

c= tk.Canvas(root,background = "#D2D2D2",yscrollcommand=vscrollbar.set)

vscrollbar.config(command=c.yview)
vscrollbar.pack(side=tk.LEFT, fill=tk.Y) 

f=tk.Frame(c) #Create the frame which will hold the widgets

c.pack(side="left", fill="both", expand=True)

#Updated the window creation
c.create_window(0,0,window=f, anchor='nw')

#Added more content here to activate the scroll
for i in range(100):
    tk.Label(f,wraplength=350 ,text=r"Det er en kendsgerning, at man bliver distraheret af læsbart indhold på en side, når man betragter dens websider, som stadig er på udviklingsstadiet. Der har været et utal af websider, som stadig er på udviklingsstadiet. Der har været et utal af variationer, som er opstået enten på grund af fejl og andre gange med vilje (som blandt andet et resultat af humor).").pack()
    tk.Button(f,text="anytext").pack()

#Removed the frame packing
#f.pack()

#Updated the screen before calculating the scrollregion
root.update()
c.config(scrollregion=c.bbox("all"))

root.mainloop()

感谢 Bryan Oakley 提供的精彩答案。

如何在Tkinter中的画布区域内使用grid()选项? - MathanKumar

0

很简单,你把c.create存储在一个元组中!

from tkinter import *
root = Tk()
c = Canvas(root, width=500, height=400).pack()
scroll = c.create_rectangle(225,175,175,225,fill='black'),c.create_rectangle(225,175,275,225)
while True:
      x1 = 1
      c.move(scroll,x1,0)
canvas.mainloop()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接