You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:15:12