Python Tkinter:如何使用可根据窗口大小调整大小的滚动条制作固定画布大小

Python Tkinter:如何使用可根据窗口大小调整大小的滚动条制作固定画布大小,python,tkinter,scrollbar,tkinter-canvas,Python,Tkinter,Scrollbar,Tkinter Canvas,我正在尝试创建带有滚动条的固定大小画布小部件。讨论中的画布可能相当大,几乎肯定会比包含它的框架大得多。我想保持画布的固定大小,但能够调整包含它的窗口的大小。我遇到的问题是我不知道如何将滚动条绑定到窗口边缘 我已经试过了.pack和.grid。grid的一个明显问题是,它只会将滚动条放在画布旁边。不幸的是,画布必须有一个固定的大小,它总是比窗口大。无论何时I.pack,画布都会随着窗口的变化而调整大小,即使我显式禁用了expand并将fill设置为None 我已将背景设置为黑色,以便清楚地看到画布

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

我已经试过了.pack和.grid。grid的一个明显问题是,它只会将滚动条放在画布旁边。不幸的是,画布必须有一个固定的大小,它总是比窗口大。无论何时I.pack,画布都会随着窗口的变化而调整大小,即使我显式禁用了expand并将fill设置为None

我已将背景设置为黑色,以便清楚地看到画布区域


将tkinter作为tk导入
从tkinter进口*
类对话框创建(tk.Frame):
定义初始化(自身,父级):
tk.Frame.\uuuu init\uuuuu(自,父)
self.xbar=tk.Scrollbar(父级,方向=水平)
self.xbar.pack(侧面=底部,填充=X)
self.ybar=tk.Scrollbar(父级)
self.ybar.pack(侧=右侧,填充=Y)
self.item_canvas=tk.canvas(父级,宽度=5000,高度=5000,xscrollcommand=self.xbar.set,yscrollcommand=self.ybar.set)
self.item_canvas.pack(side=LEFT,expand=FALSE,fill=None)
self.item\u canvas.configure(background='black')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
root=tk.tk()
对话框创建(根)
root.title(“编辑”)
root.mainloop()
画布是一个巨大的5000x5000,所以当窗口很小时,我肯定能够滚动。我希望滚动条保持与窗口边缘齐平,而不调整画布的大小。无论窗口大小,滚动条都保持休眠状态。我假设画布正在随窗口调整大小,这肯定不是期望的结果


最终,该画布将显示多个图像,并且这些图像在画布上的位置不得更改。我不认为问题在于我如何绑定滚动条(我检查了本网站上的其他几篇帖子以确保),但如果我错过了这样明显的东西,这也不是不正常的。

当你说你想要创建一个固定大小的画布时,我假设你的意思是你想要一个固定大小的可绘制区域,而不是为画布的可视部分设置固定的大小

为此,需要将
scrollregion
属性设置为可绘制区域。使用
宽度
高度
属性设置画布可见部分的大小

此外,连接滚动条是一条双向的道路:您必须配置画布以更新滚动条,并配置滚动条以滚动画布

注意:您创建了
对话框
一个
框架
,但是您将所有小部件直接放在父窗口中。这很不寻常,也不是最好的方法。我建议像您一样从
Frame
继承,但是所有小部件都应该进入
self
而不是父窗口

这样做时,您需要确保在
对话框创建
的实例上调用
pack
,例如:

dr = DialogueCreation(root)
dr.pack(fill="both", expand=True)
使用包 使用
pack
,如果希望用户调整窗口大小时可见部分增大或缩小,则应将
expand
选项设置为
True

我个人的经验是,如果将小部件创建和小部件布局分开,代码更容易理解和维护。下面的代码显示了如何使用
pack
重写您的代码。请注意用于配置
xbar
ybar
以及设置
滚动区域的附加行

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
时需要记住的重要一点是,当窗口作为一个整体改变大小时,行和列不会自动增长或收缩。您必须明确地告诉tkinter哪些行和列要增长和收缩

要实现与使用
pack
相同的效果,需要将零行和零列配置为所有额外空间。你可以给他们一个大于零的
权重

要使用
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)

问题是滚动区域设置。我最初将滚动条配置为更新,但这些行一定是在我疯狂的代码编辑中被删除的。grid的问题是,在没有设置scrollregion的情况下,它强制滚动条始终位于画布的边缘,这超出了窗口的范围。谢谢。@Brandon:这不是grid的问题。网格的使用与滚动条的工作方式完全无关。我理解,我的误解不是滚动条的功能。问题在于小部件的几何结构。使用.grid放置滚动条时,滚动条被放置在画布的下方和旁边。因为画布大小是固定的,并且没有设置滚动区域,所以滚动条不可见,除非窗口扩展到画布的大尺寸。设置滚动区域允许画布的可视区域调整大小,而无需调整画布本身的大小,因此滚动条能够在窗口中保持可见。至少这是我的理解。