Tkinter Canvas&滚动条

时间:2017-02-14 22:18:58

标签: python canvas tkinter scrollbar

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

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 个答案:

答案 0 :(得分:2)

如果要在画布中嵌入框架,则必须使用create_window,而不是pack。第一步是删除f.pack()

其次,你需要在 tkinter有机会显示小部件之后设置bbox ,因为它们的大小在实际绘制在屏幕上之前无法计算。

一种简单的方法是在调用root.update()之前调用c.config(scrollregion=c.bbox("all")),或者安排该命令与after_idle一起运行。

您的代码中的另一个错误(我假设...)是您在(0,0)处创建窗口但不设置锚点。这意味着当我猜测你想让左上角为(0,0)时,内部框架将以(0,0)为中心。

create_window来电更改为:

c.create_window(0,0,window=f, anchor='nw')

答案 1 :(得分:1)

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的出色回答。

答案 2 :(得分: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()