如何让Tkinter Canvas自适应窗口大小(无需硬编码宽高)
让Canvas适配Tkinter窗口(不硬编码宽高)
需求
让Canvas填满整个Tkinter窗口,且初始化Canvas时不硬编码宽高,当前Canvas未占满窗口,存在空白区域。
原代码
import PIL.Image from PIL import Image, ImageTk from tkinter import * class ExampleApp(Frame): def __init__(self,master): Frame.__init__(self,master=None) self.canvas = Canvas(self) self.sbarv=Scrollbar(self,orient=VERTICAL) self.sbarh=Scrollbar(self,orient=HORIZONTAL) self.sbarv.config(command=self.canvas.yview) self.sbarh.config(command=self.canvas.xview) self.canvas.config(yscrollcommand=self.sbarv.set) self.canvas.config(xscrollcommand=self.sbarh.set) self.canvas.grid(row=0,column=0,sticky="nsew") self.sbarv.grid(row=0,column=1,stick="ns") self.sbarh.grid(row=1,column=0,sticky="ew") self.im = PIL.Image.open("a.png") self.imw,self.imh=self.im.size self.canvas.config(scrollregion=(0,0,self.imw,self.imh)) self.tk_im = ImageTk.PhotoImage(self.im) self.canvas.create_image(0,0,anchor="nw",image=self.tk_im) if __name__ == "__main__": root=Tk() app = ExampleApp(root) app.grid(sticky="nsew") root.geometry(f"{1000}x{600}") root.mainloop()
修改后的代码
import PIL.Image from PIL import Image, ImageTk from tkinter import * class ExampleApp(Frame): def __init__(self, master): super().__init__(master) self.master = master # 配置Frame的网格权重,让内部组件可拉伸 self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.canvas = Canvas(self) self.sbarv = Scrollbar(self, orient=VERTICAL, command=self.canvas.yview) self.sbarh = Scrollbar(self, orient=HORIZONTAL, command=self.canvas.xview) self.canvas.config(yscrollcommand=self.sbarv.set, xscrollcommand=self.sbarh.set) self.canvas.grid(row=0, column=0, sticky="nsew") self.sbarv.grid(row=0, column=1, sticky="ns") self.sbarh.grid(row=1, column=0, sticky="ew") # 绑定大小变化事件,动态调整Canvas self.canvas.bind("<Configure>", self.on_canvas_resize) self.im = PIL.Image.open("a.png") self.imw, self.imh = self.im.size self.canvas.config(scrollregion=(0, 0, self.imw, self.imh)) self.tk_im = ImageTk.PhotoImage(self.im) self.canvas.create_image(0, 0, anchor="nw", image=self.tk_im) def on_canvas_resize(self, event): # 同步Canvas宽高与窗口变化 self.canvas.config(width=event.width, height=event.height) if __name__ == "__main__": root = Tk() # 配置root的网格权重,让Frame可随窗口拉伸 root.rowconfigure(0, weight=1) root.columnconfigure(0, weight=1) app = ExampleApp(root) app.grid(sticky="nsew") root.geometry("1000x600") root.mainloop()
关键修改说明
- 修正Frame初始化逻辑,确保组件层级关联正确,避免master参数错误
- 给
root和ExampleApp分别配置网格权重,让容器能随窗口大小自动拉伸 - 给Canvas绑定
<Configure>事件,在窗口或Canvas尺寸变化时,动态调整Canvas宽高,实现全屏适配 - 移除硬编码的Canvas宽高,完全依赖布局配置和事件响应实现自适应
内容的提问来源于stack exchange,提问作者Mhmd Admn
相关产品推荐
相关产品推荐

