代码之家  ›  专栏  ›  技术社区  ›  K-Doe

用窗口调整画布大小-好方法吗?

  •  0
  • K-Doe  · 技术社区  · 7 年前

    我创建了一个内有画布的窗口。画布包含一个矩形。两者都通过回调和窗口大小一起更改大小。

    所以我的初级问题是:它很好用,但这是一种好的还是常见的方法?或者有没有更有效/通用的方法?

    from tkinter import* #
    
    #creating instance of tkinter
    obj = Tk()  
    #Set title of our window form  
    obj.title("MyFirst Window - WOW")
    #Set dimension of form 
    x_size = 1200
    y_size = 600
    obj.geometry(str(x_size)+"x"+str(y_size)) 
    
    obj.update()
    
    w = Canvas(obj, width=x_size, height=y_size)
    w.place(x=0,y=obj.winfo_height()-100)
    w.create_rectangle(0, 0, obj.winfo_width(), 100, fill="#476042")
    
    def callback(event):
        print(str(obj.winfo_width())+'x'+str(obj.winfo_height()))
        w.config(width=obj.winfo_width(),height=obj.winfo_height())
        w.place(x=0,y=obj.winfo_height()-100)
        w.create_rectangle(0, 0, obj.winfo_width(), 100, fill="#476042")
    
    window = obj
    window.bind("<Configure>", callback)
    
    obj.mainloop()
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Bryan Oakley    7 年前

    不,这不是调整画布大小的好方法。你几乎不应该使用 place grid pack 使创建自动调整大小的小部件变得更加容易。

    例如,如果希望画布始终为100像素高,并填充窗口的整个宽度,可以将其添加到 obj 像这样:

    w = Canvas(obj, width=x_size, height=100)
    w.pack(side="bottom", fill="x")
    

    至于绿色矩形,除了在 <Configure> 如果希望矩形随画布一起增长和收缩。

    但是,每次调用回调时,都会创建一个新矩形,而不是修改现有矩形的坐标。这是内存泄漏,因为程序运行的时间越长,窗口大小调整的频率越高,将使用越来越多的内存。 w.create_rectangle 将返回标识符;您可以使用该标识符稍后修改矩形。

    这是您的代码的简化版本。我更改了变量名,使其更易于理解。

    from tkinter import *
    
    window = Tk()  
    window.title("MyFirst Window - WOW")
    x_size = 1200
    y_size = 600
    window.geometry(str(x_size)+"x"+str(y_size)) 
    
    window.update_idletasks()
    
    canvas = Canvas(window, width=x_size, height=100, background="bisque")
    canvas.pack(side="bottom", fill="x")
    rect = canvas.create_rectangle(0, 0, window.winfo_width(), 100, fill="#476042")
    
    def callback(event):
        canvas.coords(rect, 0, 0, canvas.winfo_width(), 100)
    
    canvas.bind("<Configure>", callback)
    window.mainloop()