Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Auto resize Canvas to fit tkinter window

so I want to make the canvas fit all the window but currently it’s like this:
ss

I want to do it without hard coding the width and height when initiating the canvas.

here’s the code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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()

>Solution :

You can bind a callback to resize the canvas when its parent is resized

I’ve made some changes here to make this a more prototypical tkinter app example, e.g.: using import tkinter as tk, having the main app class inherit from tk.Tk, fix setting geometry, etc.

import PIL.Image
from PIL import Image, ImageTk
import tkinter as tk


class ExampleApp(tk.Tk):
    def __init__(self) -> None:
        super().__init__()  # initialize Tk
        self.geometry('1000x600')
        self.canvas = tk.Canvas(self)

        self.sbarv = tk.Scrollbar(self, orient='vertical')
        self.sbarh = tk.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)
        
        # bind the callback to dynamically resize the canvas
        self.bind('<Configure>', self.resize_canvas)

        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)

    def resize_canvas(self, _event) -> None:
        '''Dynamically resize the canvas as the window changes'''
        # subtracting 20 from the width & height accommodates the scrollbars
        self.canvas.configure(
            width=self.winfo_width() - 20,
            height=self.winfo_height() - 20,
        )


if __name__ == "__main__":
    root = ExampleApp()   # instantiate your main app class
    root.mainloop()  # start the tkinter event loop
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading