Tkinter:如何使用调整大小为 window 的滚动条制作固定的 canvas 大小
Tkinter: How to make a fixed canvas size with scroll bars that resize to the window
我正在尝试创建带有滚动条的固定大小 canvas 小部件。所讨论的 canvas 可能非常大,而且几乎肯定会比包含它的框架大得多。我想将 canvas 保持在其固定大小,但能够调整包含它的 window 的大小。我遇到的问题是我不知道如何将滚动条绑定到 window.
的边缘
.pack 和.grid 都试过了。 .grid 的一个明显问题是它只会将滚动条放在 canvas 旁边。不幸的是,canvas 必须有一个固定的大小,它总是比 window 大。每当我 .pack 时,canvas 似乎会随着 window 调整大小,即使我明确禁用扩展并将填充设置为 None。
我将背景设置为黑色,目的是为了清楚地看到 canvas 区域。
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()
canvas 是一个巨大的 5000x5000,所以当 window 很小的时候我应该绝对能够滚动。我希望滚动条与 window 的边缘保持齐平,而不调整 canvas 的大小。无论 window 有多大或多小,滚动条都保持休眠状态。我假设 canvas 正在使用 window 调整大小,这绝对不是想要的结果。
最终这个 canvas 上会显示几张图片,并且这些图片的位置不得在 canvas 上更改。我认为问题不在于我如何绑定滚动条(我检查了该网站上的其他几篇文章以确保),但如果我错过了类似这样明显的东西,那也不会不正常。
当您说要创建固定大小 canvas 时,我假设您的意思是您希望可绘制区域为固定大小,而不是可视部分的固定大小canvas.
为此,您需要将 scrollregion
属性设置为可绘制区域。您使用 width
和 height
属性来设置 canvas.
的可见部分的大小
此外,连接滚动条有两条路:您必须配置 canvas 来更新滚动条,并配置滚动条来滚动 canvas。
注意:您将 DialogCreation
设为 Frame
,但您将所有小部件直接放在父级中。这是非常不寻常的,而且不是最好的方法。我建议像您一样从 Frame
继承,但是所有小部件都应该放在 self
而不是父级中。
当您这样做时,您需要确保在 DialogCreation
的实例上调用 pack
,例如:
dr = DialogueCreation(root)
dr.pack(fill="both", expand=True)
使用包
对于 pack
,如果您希望可见部分在用户调整 window 大小时增大或缩小,则应将 expand
选项设置为 True
。 =36=]
我的个人经验是,如果将小部件创建与小部件布局分开,代码将更易于理解和维护。以下代码显示了我将如何使用 pack
重写您的代码。请注意用于配置 xbar
和 ybar
以及设置 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)
使用网格
The obvious issue with .grid is that it will simply place the scroll bars next to the canvas.
我认为这根本不明显。 grid
没有这样的限制。您可以将滚动条放在任何您想要的位置。
使用 grid
需要记住的重要一点是,当 window 作为一个整体改变大小时,行和列不会自动增大或缩小。你必须明确地告诉 tkinter 哪些行和列要增长和收缩。
要达到与使用 pack
相同的效果,您需要配置第 0 行、第 0 列全部额外 space。您可以通过给他们一个大于零的 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)
我正在尝试创建带有滚动条的固定大小 canvas 小部件。所讨论的 canvas 可能非常大,而且几乎肯定会比包含它的框架大得多。我想将 canvas 保持在其固定大小,但能够调整包含它的 window 的大小。我遇到的问题是我不知道如何将滚动条绑定到 window.
的边缘.pack 和.grid 都试过了。 .grid 的一个明显问题是它只会将滚动条放在 canvas 旁边。不幸的是,canvas 必须有一个固定的大小,它总是比 window 大。每当我 .pack 时,canvas 似乎会随着 window 调整大小,即使我明确禁用扩展并将填充设置为 None。
我将背景设置为黑色,目的是为了清楚地看到 canvas 区域。
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()
canvas 是一个巨大的 5000x5000,所以当 window 很小的时候我应该绝对能够滚动。我希望滚动条与 window 的边缘保持齐平,而不调整 canvas 的大小。无论 window 有多大或多小,滚动条都保持休眠状态。我假设 canvas 正在使用 window 调整大小,这绝对不是想要的结果。
最终这个 canvas 上会显示几张图片,并且这些图片的位置不得在 canvas 上更改。我认为问题不在于我如何绑定滚动条(我检查了该网站上的其他几篇文章以确保),但如果我错过了类似这样明显的东西,那也不会不正常。
当您说要创建固定大小 canvas 时,我假设您的意思是您希望可绘制区域为固定大小,而不是可视部分的固定大小canvas.
为此,您需要将 scrollregion
属性设置为可绘制区域。您使用 width
和 height
属性来设置 canvas.
此外,连接滚动条有两条路:您必须配置 canvas 来更新滚动条,并配置滚动条来滚动 canvas。
注意:您将 DialogCreation
设为 Frame
,但您将所有小部件直接放在父级中。这是非常不寻常的,而且不是最好的方法。我建议像您一样从 Frame
继承,但是所有小部件都应该放在 self
而不是父级中。
当您这样做时,您需要确保在 DialogCreation
的实例上调用 pack
,例如:
dr = DialogueCreation(root)
dr.pack(fill="both", expand=True)
使用包
对于 pack
,如果您希望可见部分在用户调整 window 大小时增大或缩小,则应将 expand
选项设置为 True
。 =36=]
我的个人经验是,如果将小部件创建与小部件布局分开,代码将更易于理解和维护。以下代码显示了我将如何使用 pack
重写您的代码。请注意用于配置 xbar
和 ybar
以及设置 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)
使用网格
The obvious issue with .grid is that it will simply place the scroll bars next to the canvas.
我认为这根本不明显。 grid
没有这样的限制。您可以将滚动条放在任何您想要的位置。
使用 grid
需要记住的重要一点是,当 window 作为一个整体改变大小时,行和列不会自动增大或缩小。你必须明确地告诉 tkinter 哪些行和列要增长和收缩。
要达到与使用 pack
相同的效果,您需要配置第 0 行、第 0 列全部额外 space。您可以通过给他们一个大于零的 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)