滚动条无法在画布上工作

时间:2016-11-27 19:12:21

标签: python tkinter scrollbars

我正在使用tkinter在python中创建一个json编辑器。

我已经通过创建Canvas添加了一个滚动条,并在其中添加了Frame

然后我将Scrollbar命令设置为canvas.yview。

有两件事搞砸了,我不明白为什么。

  1. 当我按滚动按钮(向上和向下箭头)时画布不滚动

  2. 我现在正在将滚动条打包到窗口(根)而不是框架上,因为每当我将它打包到框架上时,tkinter应用程序都不会打开,我的计算机风扇开始打开...有谁知道这里发生了什么? (因此,如果您尝试运行代码,滚动条很小)

  3. 这是我的代码:

    编辑>代码缩短

    import Tkinter as tk
    import webbrowser
    import os
    import bjson as bj
    
    class App:
        def __init__(self, master):
            self.window = master
            self.window.geometry("800x450")
            self.canvas = tk.Canvas(self.window, width=800, height=400)
            self.master = tk.Frame(self.canvas, width=800, height=400)
            self.canvas.pack()
            self.master.place(x=0, y=0)
            scrollbar = tk.Scrollbar(self.window)
            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
            scrollbar.config(command=self.canvas.yview)
    
        def init(self):
            master = self.master
            self.frames = {
                "Home": HomeFrame(master)
            }
            self.openFrame = None
            self.loadFrame("Home")
    
        def loadFrame(self, frame):
            self.openFrame = self.frames[frame]
            self.openFrame.display()
    
        def setTitle(self, t):
            self.window.title(t)
    
    class Frame:
        def __init__(self, master):
            self.master = master
            self.frame = tk.Frame(master)
            self.frame.grid(row=0, column=0, sticky='news')
            self.init()
            self.frame_create()
    
        def display(self):
            self.frame.tkraise()    #raises frame to top
            self.frame_load()       #initializes the frame
    
        def clear(self):
            for widget in self.frame.winfo_children():
                widget.destroy()
    
        def init(self): pass
        def frame_load(self): pass
        def frame_create(self): pass
    
    class HomeFrame(Frame):
        def frame_create(self):
            p = self.frame
            for i in range(20):
                tk.Label(p, text="This is content... " + str(i)).pack()
                for j in range(2):
                    LineBreak(p)
    
    def LineBreak(p):
        tk.Label(p, text="").pack()
    
    root = tk.Tk()
    glob = {}
    app = App(root)
    app.init()
    root.mainloop()
    

    它有点长,有点乱,但你应该看看我是如何在__init__的{​​{1}}中添加滚动条

    任何人都知道发生了什么,以及如何解决这个问题?

    提前致谢!

1 个答案:

答案 0 :(得分:0)

您的代码有很多问题。但是,滚动条无法正常工作的问题与您忽略的两件事有关:

首先,滚动条和小部件需要双向通信。需要告诉画布滚动条,并且需要告诉滚动条有关画布的信息。你正在做一个而不是另一个:

self.canvas.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=self.canvas.yview)

其次,您需要配置画布的scrollregion属性。这告诉tkinter您想要查看的较大虚拟画布的哪个部分。通常,这是在画布的<Configure>方法的绑定中完成的,通常您需要将其设置为画布中所有内容的边界框。对于后者,您可以将字符串"all"传递给bbox方法:

self.canvas.configure(scrollregion=self.canvas.bbox("all"))

如果您知道要滚动的区域的确切大小,可以将其设置为该值(例如:scrollregion=(0,0,1000,1000)以在1000x1000像素的区域内滚动)。

第2点的原因是您不能同时使用packgrid来共享同一个父级的小部件。当你这样做时,你将获得你描述的行为。这是因为grid将尝试布局所有小部件。这可能会导致某些小部件改变大小。 pack会注意到一个或多个小部件大小的变化,并尝试重新布局所有小部件。这可能会导致某些小部件改变大小。 grid会注意到一个或多个小部件大小的变化,并尝试重新布局所有小部件。等等。