【问题标题】:Tkinter Canvas & ScrollbarTkinter 画布和滚动条
【发布时间】:2017-07-03 09:38:09
【问题描述】:

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

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() 函数以可滚动的方式显示它。

现在窗口已显示,但滚动条未启用 - 就像滚动区域不正确或滚动条和画布之间的链接不正确。

【问题讨论】:

    标签: python canvas tkinter scrollbar


    【解决方案1】:

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

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

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

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

    将您的 create_window 电话更改为如下所示:

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

    【讨论】:

    • 这太棒了 - 非常感谢!我会测试一下然后回来
    【解决方案2】:
    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() 选项?
    【解决方案3】:

    很简单,将 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()
    

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 1970-01-01
      • 2015-02-08
      • 2011-12-05
      • 2019-01-19
      • 2015-12-18
      • 2019-07-24
      • 2017-09-29
      • 1970-01-01
      相关资源
      最近更新 更多