I need to get a canvas in tkinter to set its width to the width of the window, and then dynamically re-size the canvas when the user makes the window smaller/bigger.
Is there any way of doing this (easily)?
Resizing the canvas on the fly is quite easy. To do it, simply set the width and height properties of the Canvas object, and then redraw the canvas contents: Canvas . width = 600 ; Canvas .
Build A Paint Program With TKinter and Python Let us suppose that we want to make a non-resizable window in an application. In this case, we can use resizable(height, width) and pass the value of height=None and width=None. The method also works by passing Boolean values as resizable(False, False).
Python Tkinter Canvas size can be decided by providing height and width. Height is the vertical position of canvas on the parent window. Width is the horizontal position of the canvas on the parent window. Change in the height & width will change the size of the canvas.
To set a specific size to the window when using Python tkinter, use geometry() function on the Tk() class variable. where width and height should be replaced with integers that represent the width and height of the window respectively.
I thought I would add in some extra code to expand on @fredtantini's answer, as it doesn't deal with how to update the shape of widgets drawn on the Canvas
.
To do this you need to use the scale
method and tag all of the widgets. A complete example is below.
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()
You can use the .pack
geometry manager:
self.c=Canvas(…) self.c.pack(fill="both", expand=True)
should do the trick. If your canvas is inside a frame, do the same for the frame:
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)
See effbot for more info.
Edit: if you don't want a "full sized" canvas, you can bind your canvas to a function:
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)
See effbot again for events and bindings
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With