Python tkinter 框架 canvas 调整大小
Python tkinter frame canvas resize
我正在尝试调整 canvas 的大小,以便在用户使用 [=48= 调整 window 大小时 canvas 填充整个 window ] 在 window 边缘,但我没有成功。
我查看了以下其他问题:
问题 #1(之前已发布,但在这里没有帮助)
这个人向我发送了我认为正确的方向,因为我在 canvas 上绑定了一个 Configure。但是,我收到一条错误消息“'canvas' 未在 FrameWidth 中定义。”
如果我修改了函数调用和函数,那么我得到的错误是"TypeError: FrameWidth() missing 1 required positional argument: 'canvas' " The modification is
canvas.bind('<Configure>', self.FrameWidth(canvas))
def FrameWidth(self, event, canvas):
问题 #2(之前已发布,但在这里没有帮助)
我也看了这个问题:
但是这个问题是在解决一个行为不稳定的滚动条。
问题 #3(之前已发布,但在这里没有帮助)
我也看过这个问题并输入 weight=1,但这没有帮助:
Python TKinter: frame and canvas will expand horizontally, but not vertically, when window is resized
如有任何建议,我们将不胜感激。
这是我的 MWE:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 3 04:39:43 2017
@author: davidc
"""
import tkinter as tk
class Selections(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.FifthLabelLeft = tk.Label(self,
text="""Riding""",
justify = tk.CENTER,
width=20,
padx = 10).grid(row=4, column = 0, pady=5)
self.FifthLabelCenter = tk.Label(self,
text="""Winning Candidate""",
justify = tk.CENTER,
width=20,
padx = 10).grid(row=4, column = 1, pady=5)
self.FifthLabelRight = tk.Label(self,
text="""Percent of Vote""",
justify = tk.CENTER,
width=10,
padx = 10).grid(row=4, column = 2, pady=5)
mybox = tk.LabelFrame(self, padx=5, pady=4)
mybox.grid(row=5, column=0, columnspan=3)
canvas = tk.Canvas(mybox, borderwidth=5, background="#70ff33")
frame = tk.Frame(canvas, background="#33f4ff")
vsb = tk.Scrollbar(mybox, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set, width=450, heigh=30)
mybox.grid_columnconfigure(5,weight=1)
mybox.grid_rowconfigure(5,weight=1)
frame.grid_columnconfigure(5,weight=1)
frame.grid_rowconfigure(5,weight=1)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")
# be sure that we call OnFrameConfigure on the right canvas
frame.bind("<Configure>", lambda event: self.OnFrameConfigure(canvas))
canvas.bind('<Configure>', self.FrameWidth)
self.fillWindow(frame)
self.QuitButton = tk.Button(self,
text="QUIT",
command=root.destroy,
padx=25, pady=0)
self.QuitButton.grid(column = 0, columnspan=3)
def fillWindow(self, frame):
PartyWinnersList = [['Some list of places', "Somebody's Name", 0.37448599960838064],
['A shorter list', 'Three Long Names Here', 0.52167817821240514],
['A much longer, longer entry', 'Short Name', 0.41945832387008858]]
placement = 2
for i in PartyWinnersList:
ShowYear = tk.Label(frame,
text="""%s """ % i[0],
width=20,
)
ShowYear.grid(row=placement, column = 0, sticky=tk.S)
ShowSystem = tk.Label(frame,
text="""%s """ % i[1],
width=20,
)
ShowSystem.grid(row=placement, column = 1, sticky=tk.N)
PercentVotes = i[2]*100
ShowVotes = tk.Label(frame,
text="""%3.1f""" % PercentVotes,
width=10,
)
ShowVotes.grid(row=placement, column = 2, sticky=tk.N)
placement += 1
def FrameWidth(self, event):
canvas_width = event.width
canvas.itemconfig(self.canvas_frame, width = canvas_width)
def OnFrameConfigure(self, canvas):
canvas.configure(scrollregion=canvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
main = Selections(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
无需在这里重新发明轮子。 Canvas()
是一个 tkinter 小部件,和所有 tkinter 小部件一样,它必须使用几何管理器在 window 中绘制。这意味着我们可以操纵它在 window.
中的显示方式
下面的示例程序是根据 this page.
上的示例修改而来的
如果我们使用 .pack()
那么我们可以做如下的事情:
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack(fill="both", expand=True)
w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
w.create_rectangle(50, 25, 150, 75, fill="blue")
root.mainloop()
其中 fill="both"
和 expand=True
的组合告诉小部件吃掉它在 window 中提供的所有额外 space 并扩展以填充它。
如果我们使用 .grid()
那么我们必须做一些稍微不同的事情:
from tkinter import *
root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
w = Canvas(root, width=200, height=100)
w.grid(sticky=N+S+E+W)
w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
w.create_rectangle(50, 25, 150, 75, fill="blue")
root.mainloop()
这里我们使用 .rowconfigure()
和 .columnconfigure
告诉第 0 行和第 0 列(我们的 canvas 所在的位置)比任何其他行或列具有更高的权重,这意味着它们在 window 中获得比其他更多的免费 space(在这种情况下,所有这些看起来都没有其他行或列存在),然后我们需要告诉小部件实际扩展"cell" 它所在的位置,我们通过指定 sticky=N+S+E+W
来做到这一点,它告诉小部件在展开时粘附在单元格的所有 4 个边缘上,从而展开小部件。
我正在尝试调整 canvas 的大小,以便在用户使用 [=48= 调整 window 大小时 canvas 填充整个 window ] 在 window 边缘,但我没有成功。
我查看了以下其他问题:
问题 #1(之前已发布,但在这里没有帮助)
这个人向我发送了我认为正确的方向,因为我在 canvas 上绑定了一个 Configure。但是,我收到一条错误消息“'canvas' 未在 FrameWidth 中定义。”
如果我修改了函数调用和函数,那么我得到的错误是"TypeError: FrameWidth() missing 1 required positional argument: 'canvas' " The modification is
canvas.bind('<Configure>', self.FrameWidth(canvas))
def FrameWidth(self, event, canvas):
问题 #2(之前已发布,但在这里没有帮助)
我也看了这个问题:
但是这个问题是在解决一个行为不稳定的滚动条。
问题 #3(之前已发布,但在这里没有帮助)
我也看过这个问题并输入 weight=1,但这没有帮助:
Python TKinter: frame and canvas will expand horizontally, but not vertically, when window is resized
如有任何建议,我们将不胜感激。
这是我的 MWE:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 3 04:39:43 2017
@author: davidc
"""
import tkinter as tk
class Selections(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.FifthLabelLeft = tk.Label(self,
text="""Riding""",
justify = tk.CENTER,
width=20,
padx = 10).grid(row=4, column = 0, pady=5)
self.FifthLabelCenter = tk.Label(self,
text="""Winning Candidate""",
justify = tk.CENTER,
width=20,
padx = 10).grid(row=4, column = 1, pady=5)
self.FifthLabelRight = tk.Label(self,
text="""Percent of Vote""",
justify = tk.CENTER,
width=10,
padx = 10).grid(row=4, column = 2, pady=5)
mybox = tk.LabelFrame(self, padx=5, pady=4)
mybox.grid(row=5, column=0, columnspan=3)
canvas = tk.Canvas(mybox, borderwidth=5, background="#70ff33")
frame = tk.Frame(canvas, background="#33f4ff")
vsb = tk.Scrollbar(mybox, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set, width=450, heigh=30)
mybox.grid_columnconfigure(5,weight=1)
mybox.grid_rowconfigure(5,weight=1)
frame.grid_columnconfigure(5,weight=1)
frame.grid_rowconfigure(5,weight=1)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")
# be sure that we call OnFrameConfigure on the right canvas
frame.bind("<Configure>", lambda event: self.OnFrameConfigure(canvas))
canvas.bind('<Configure>', self.FrameWidth)
self.fillWindow(frame)
self.QuitButton = tk.Button(self,
text="QUIT",
command=root.destroy,
padx=25, pady=0)
self.QuitButton.grid(column = 0, columnspan=3)
def fillWindow(self, frame):
PartyWinnersList = [['Some list of places', "Somebody's Name", 0.37448599960838064],
['A shorter list', 'Three Long Names Here', 0.52167817821240514],
['A much longer, longer entry', 'Short Name', 0.41945832387008858]]
placement = 2
for i in PartyWinnersList:
ShowYear = tk.Label(frame,
text="""%s """ % i[0],
width=20,
)
ShowYear.grid(row=placement, column = 0, sticky=tk.S)
ShowSystem = tk.Label(frame,
text="""%s """ % i[1],
width=20,
)
ShowSystem.grid(row=placement, column = 1, sticky=tk.N)
PercentVotes = i[2]*100
ShowVotes = tk.Label(frame,
text="""%3.1f""" % PercentVotes,
width=10,
)
ShowVotes.grid(row=placement, column = 2, sticky=tk.N)
placement += 1
def FrameWidth(self, event):
canvas_width = event.width
canvas.itemconfig(self.canvas_frame, width = canvas_width)
def OnFrameConfigure(self, canvas):
canvas.configure(scrollregion=canvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
main = Selections(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
无需在这里重新发明轮子。 Canvas()
是一个 tkinter 小部件,和所有 tkinter 小部件一样,它必须使用几何管理器在 window 中绘制。这意味着我们可以操纵它在 window.
下面的示例程序是根据 this page.
上的示例修改而来的如果我们使用 .pack()
那么我们可以做如下的事情:
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack(fill="both", expand=True)
w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
w.create_rectangle(50, 25, 150, 75, fill="blue")
root.mainloop()
其中 fill="both"
和 expand=True
的组合告诉小部件吃掉它在 window 中提供的所有额外 space 并扩展以填充它。
如果我们使用 .grid()
那么我们必须做一些稍微不同的事情:
from tkinter import *
root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
w = Canvas(root, width=200, height=100)
w.grid(sticky=N+S+E+W)
w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
w.create_rectangle(50, 25, 150, 75, fill="blue")
root.mainloop()
这里我们使用 .rowconfigure()
和 .columnconfigure
告诉第 0 行和第 0 列(我们的 canvas 所在的位置)比任何其他行或列具有更高的权重,这意味着它们在 window 中获得比其他更多的免费 space(在这种情况下,所有这些看起来都没有其他行或列存在),然后我们需要告诉小部件实际扩展"cell" 它所在的位置,我们通过指定 sticky=N+S+E+W
来做到这一点,它告诉小部件在展开时粘附在单元格的所有 4 个边缘上,从而展开小部件。