【问题标题】:Scrollbar not working on canvas滚动条在画布上不起作用
【发布时间】:2016-11-27 19:12:20
【问题描述】:

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

我通过创建Canvas 并在其中放入Frame 添加了一个滚动条。

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

有两件事搞砸了,我不知道为什么。

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

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

这是我的代码:

EDIT>代码缩短

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__App 中添加滚动条的

任何人都知道发生了什么,以及如何解决它?

提前致谢!

【问题讨论】:

标签: python tkinter scrollbars


【解决方案1】:

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

首先,滚动条和小部件需要两种方式的通信。画布需要被告知滚动条,滚动条需要被告知画布。你正在做一个但不是另一个:

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 会注意到一个或多个小部件大小的变化,并尝试重新布局所有小部件。以此类推。

【讨论】:

    猜你喜欢
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多