Tkinter:如何使用滚动条调整窗口大小来固定画布大小

时间:2019-05-14 17:47:11

标签: python tkinter scrollbar tkinter-canvas

我正在尝试使用滚动条创建固定大小的画布小部件。有问题的画布可能很大,并且几乎肯定会比包含它的框架大得多。我想将画布保持在其固定大小,但是能够调整包含它的窗口的大小。我遇到的问题是我不知道如何将滚动条绑定到窗口的边缘。

我尝试了.pack和.grid。 .grid的明显问题是,它将仅将滚动条放置在画布旁边。不幸的是,画布必须具有始终大于窗口的固定大小。每当我打包时,即使我明确禁用扩展并将填充设置为“无”,画布也会随窗口调整大小。

为了清楚看到画布区域,我将背景设置为黑色。


import tkinter as tk
from tkinter import *


class DialogueCreation(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.xbar = tk.Scrollbar(parent, orient=HORIZONTAL)
        self.xbar.pack(side=BOTTOM, fill=X)

        self.ybar = tk.Scrollbar(parent)
        self.ybar.pack(side=RIGHT, fill=Y)

        self.item_canvas = tk.Canvas(parent, width=5000, height=5000, xscrollcommand=self.xbar.set, yscrollcommand=self.ybar.set)
        self.item_canvas.pack(side=LEFT, expand=FALSE, fill=None)
        self.item_canvas.configure(background='black')


if __name__ == '__main__':
    root = tk.Tk()
    DialogueCreation(root)
    root.title("Editor")
    root.mainloop()


画布的大小为5000x5000,因此当窗口较小时,我绝对应该能够滚动。我希望滚动条与窗口的边缘保持齐平,而无需调整画布的大小。无论窗口大小,滚动条都保持休眠状态。我假设画布正在随窗口调整大小,这绝对不是理想的结果。

最终,此画布上将显示多个图像,并且这些图像的位置在画布上不得更改。我不认为问题出在我如何绑定滚动条上(我检查了该网站上的其他几条帖子以确保确定),但是如果我错过了类似的事情,那并不是没有特色的。

1 个答案:

答案 0 :(得分:0)

当您说要创建固定大小的画布时,我假设您的意思是希望可绘制区域为固定大小,而不是为画布的可见部分设置固定大小。

为此,您需要将scrollregion属性设置为可绘制区域。您可以使用widthheight属性来设置画布可见部分的大小。

此外,连接滚动条是一条两条路:必须配置画布以更新滚动条,并配置滚动条以滚动画布。

注意:您将DialogCreation设为Frame,但您将所有小部件都直接放在了父级中。这是非常不寻常的,不是最好的方法。我建议像您一样从Frame继承,但是所有小部件都应该放在self中而不是父目录中。

以这种方式进行操作时,需要确保在pack的实例上调用DialogCreation,例如:

dr = DialogueCreation(root)
dr.pack(fill="both", expand=True)

使用包

对于pack,如果希望在用户调整窗口大小时可见部分增大或缩小,则应将expand选项设置为True

我的个人经验是,如果您将小部件的创建与小部件的布局分开,代码将更易于理解和维护。以下代码显示了如何使用pack重写您的代码。请注意用于配置xbarybar以及设置scrollregion的其他行。

class DialogueCreation(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.xbar = tk.Scrollbar(self, orient=HORIZONTAL)
        self.ybar = tk.Scrollbar(self)
        self.item_canvas = tk.Canvas(self, width=400, height=400,
                                     xscrollcommand=self.xbar.set,
                                     yscrollcommand=self.ybar.set)

        self.xbar.configure(command=self.item_canvas.xview)
        self.ybar.configure(command=self.item_canvas.yview)

        self.item_canvas.configure(scrollregion=(0,0,4999,4999))
        self.item_canvas.configure(background='black')

        self.xbar.pack(side=BOTTOM, fill=X)
        self.ybar.pack(side=RIGHT, fill=Y)
        self.item_canvas.pack(side=LEFT, expand=TRUE, fill=BOTH)

使用网格

  

.grid的明显问题是,它只会将滚动条放置在画布旁边。

我一点也不认为这很明显。 grid没有这样的限制。您可以将滚动条放置在任意位置。

grid要记住的重要一点是,当整个窗口更改大小时,行和列不会自动增长或收缩。您必须明确告诉tkinter要增长和缩小的行和列。

要获得与使用pack相同的效果,您需要配置零行,零列,以使其具有所有额外的空间。您可以通过给他们一个weight大于零的方式来实现。

要使用grid代替pack,请将上面示例的最后三行替换为以下六行:

self.item_canvas.grid(row=0, column=0, sticky="nsew")
self.xbar.grid(row=1, column=0, sticky="ew")
self.ybar.grid(row=0, column=1, sticky="ns")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)