Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使tkinter画布动态调整为窗口宽度?_Python_Canvas_Python 3.x_Tkinter_Autoresize - Fatal编程技术网

Python 如何使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=

我需要在tkinter中获得一个画布,将其宽度设置为窗口的宽度,然后在用户使窗口变小/变大时动态地重新调整画布的大小


有什么方法可以(轻松地)做到这一点吗?

您可以使用
.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吗?“这是稍微改变一点的响应代码”?它是如何改变的?除了已被接受的答案之外,你的答案还有什么价值?