Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get tkinter canvas to dynamically resize to window width?

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

like image 924
Annonymous Avatar asked Apr 03 '14 10:04

Annonymous


People also ask

How do you dynamically resize canvas?

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 .

How do I make my tkinter GUI resizable?

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

How do I change the size of a canvas in Python?

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.

How do I change the default tkinter window size?

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.


2 Answers

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() 
like image 167
ebarr Avatar answered Sep 23 '22 21:09

ebarr


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

like image 32
fredtantini Avatar answered Sep 21 '22 21:09

fredtantini