Python 如何使tkinter画布动态调整为窗口宽度?
我需要在tkinter中获得一个画布,将其宽度设置为窗口的宽度,然后在用户使窗口变小/变大时动态地重新调整画布的大小Python 如何使tkinter画布动态调整为窗口宽度?,python,canvas,python-3.x,tkinter,autoresize,Python,Canvas,Python 3.x,Tkinter,Autoresize,我需要在tkinter中获得一个画布,将其宽度设置为窗口的宽度,然后在用户使窗口变小/变大时动态地重新调整画布的大小 有什么方法可以(轻松地)做到这一点吗?您可以使用.pack几何图形管理器: self.c=Canvas(…) self.c.pack(fill="both", expand=True) 我们应该做到这一点。 如果画布位于框架内,请对框架执行相同操作: self.r = root self.f = Frame(self.r) self.f.pack(fill=
有什么方法可以(轻松地)做到这一点吗?您可以使用
.pack
几何图形管理器:
self.c=Canvas(…)
self.c.pack(fill="both", expand=True)
我们应该做到这一点。
如果画布位于框架内,请对框架执行相同操作:
self.r = root
self.f = Frame(self.r)
self.f.pack(fill="both", expand=True)
self.c = Canvas(…)
self.c.pack(fill="both", expand=True)
有关更多信息,请参阅
编辑:如果不需要“全尺寸”画布,可以将画布绑定到函数:
self.c.bind('<Configure>', self.resize)
def resize(self, event):
w,h = event.width-100, event.height-100
self.c.config(width=w, height=h)
self.c.bind(“”,self.resize)
def调整大小(自身、事件):
w、 h=事件宽度-100,事件高度-100
self.c.config(宽度=w,高度=h)
再次查看事件和绑定我想我应该添加一些额外的代码来扩展,因为它不涉及如何更新在
画布上绘制的小部件的形状
为此,您需要使用scale
方法并标记所有小部件。下面是一个完整的例子
from Tkinter import *
# a subclass of Canvas for dealing with resizing of windows
class ResizingCanvas(Canvas):
def __init__(self,parent,**kwargs):
Canvas.__init__(self,parent,**kwargs)
self.bind("<Configure>", self.on_resize)
self.height = self.winfo_reqheight()
self.width = self.winfo_reqwidth()
def on_resize(self,event):
# determine the ratio of old width/height to new width/height
wscale = float(event.width)/self.width
hscale = float(event.height)/self.height
self.width = event.width
self.height = event.height
# resize the canvas
self.config(width=self.width, height=self.height)
# rescale all the objects tagged with the "all" tag
self.scale("all",0,0,wscale,hscale)
def main():
root = Tk()
myframe = Frame(root)
myframe.pack(fill=BOTH, expand=YES)
mycanvas = ResizingCanvas(myframe,width=850, height=400, bg="red", highlightthickness=0)
mycanvas.pack(fill=BOTH, expand=YES)
# add some widgets to the canvas
mycanvas.create_line(0, 0, 200, 100)
mycanvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
mycanvas.create_rectangle(50, 25, 150, 75, fill="blue")
# tag all of the drawn widgets
mycanvas.addtag_all("all")
root.mainloop()
if __name__ == "__main__":
main()
从Tkinter导入*
#Canvas的一个子类,用于处理窗口的大小调整
类大小调整Canvas(画布):
定义初始值(自、父、**kwargs):
画布.\uuuuuuuuuuuuuuuuuuuuuu(自我、父母、**kwargs)
self.bind(“,self.on_resize)
self.height=self.winfo_reqheight()
self.width=self.winfo_reqwidth()
def on_resize(自我,事件):
#确定旧宽度/高度与新宽度/高度的比率
wscale=float(event.width)/self.width
hs刻度=浮动(事件高度)/自身高度
self.width=event.width
self.height=event.height
#调整画布的大小
self.config(宽度=self.width,高度=self.height)
#重新缩放使用“全部”标记标记的所有对象
自刻度(“全部”,0,0,wscale,hscale)
def main():
root=Tk()
myframe=框架(根)
myframe.pack(fill=BOTH,expand=YES)
mycanvas=ResizingCanvas(myframe,宽度=850,高度=400,bg=“red”,highlightthickness=0)
mycanvas.pack(fill=BOTH,expand=YES)
#向画布添加一些小部件
mycanvas.create_行(0,0,200,100)
mycanvas.create_line(0,100200,0,fill=“red”,dash=(4,4))
mycanvas.create_矩形(50、25、150、75,fill=“blue”)
#标记所有绘制的小部件
mycanvas.addtag_all(“全部”)
root.mainloop()
如果名称=“\uuuuu main\uuuuuuuu”:
main()
要调整画布对象的大小以适应新的窗口大小,只需正确使用tkinter几何体管理器
使用pack时有展开和填充选项,使用grid时,您需要使用canvas master(包含画布的小部件)的columnconfigure和rowconfigure方法,使用placemanager时有relwidth和relheight选项。
另一方面,这只会调整画布尺寸,而不会更改其对象的尺寸。要调整画布对象的大小,需要使用建议的缩放方法。需要考虑的另一件事是,某些画布对象(如文本)不会受到scale canvas方法的影响
以下是稍微更改的响应代码:
将tkinter作为tk导入
#Canvas的一个子类,用于处理窗口的大小调整
类大小调整Canvas(tk.Canvas):
定义初始值(自、父、**kwargs):
tk.Canvas.\uuuuu init\uuuuuuuuu(自我、父级、**kwargs)
self.bind(“,self.on_resize)
self.height=self.winfo_reqheight()
self.width=self.winfo_reqwidth()
def on_resize(自我,事件):
#确定旧宽度/高度与新宽度/高度的比率
wscale=event.width/self.width
hscale=event.height/self.height
self.width=event.width
self.height=event.height
#重新缩放所有对象
self.scale(“全部”、0、0、wscale、hscale)
def main():
root=tk.tk()
myframe=tk.Frame(根)
myframe.pack(fill=tk.BOTH,expand=tk.YES)
mycanvas=ResizingCanvas(myframe,宽度=850,高度=400,bg=“浅蓝色”)#,highlightthickness=0)
mycanvas.pack(fill=tk.BOTH,expand=tk.YES)
#向画布添加一些小部件
mycanvas.create_行(0,0,200,100)
mycanvas.create_line(0,100200,0,fill=“red”,dash=(4,4))
mycanvas.create_矩形(50、25、150、75,fill=“blue”)
#标记所有绘制的小部件
root.mainloop()
如果名称=“\uuuuu main\uuuuuuuu”:
main()
一句警告:将此与网格一起使用将杀死您的窗口管理器!现在:如果画布不是唯一的小部件,我如何让它工作?在我的例子中,画布下方有一个带按钮的框架,它被画布推出…这非常棒。我只想强调在创建ResizingCanvas时,highlightthickness=0
的重要性,否则画布会一直扩展,直到你杀死它。非常感谢!但似乎所有对象都重新缩放了,除了使用mycanvas.create\u image(cur\u image\u width/2,cur\u image\u height/2,image=cur\u image\u bg)添加到画布的图像之外。
。您知道如何使用self.scale函数重新缩放图像吗?此解决方案不太理想,因为使用画布数组进行多次调整大小事件时,最初具有相同大小的画布都将具有不同的大小。另外,如果你有一条线或一个圆,线的厚度不会改变。你能在另一个有网格的框架内使用pack吗?“这是稍微改变一点的响应代码”?它是如何改变的?除了已被接受的答案之外,你的答案还有什么价值?