65

I'm using Python and Tkinter, and I need to know the current dimensions (width, height) of a widget.

I've tried somewidget["width"], but it returns only a fixed value, and is not updated whenever the widget size changes (e.g. when the window is resized).

Denilson Sá Maia
  • 47,466
  • 33
  • 109
  • 111

3 Answers3

89

somewidget.winfo_width() and somewidget.winfo_height() give 1. You need to update Tk (issue tk.update()) before getting these values.

Apostolos
  • 3,115
  • 25
  • 28
  • 3
    Thats most important, I waster lot of time debugging this – Akshay J Mar 12 '18 at 08:17
  • I can only say classic debugging stuff again, really this should be the accepted answer. – PiMathCLanguage Dec 15 '18 at 21:41
  • 1
    Sounds like a good idea, I'm getting '1'. But what do we actually do? What is update Tk (issue tk.update()) – John White Nov 10 '19 at 22:55
  • @John, `tk.update()` updates the changes made to Tkinter up to this point. Setting new width and height after initializing Tkinter (with `tk = Tk()` or `root = Tk()`, etc.) is such a change. – Apostolos Nov 11 '19 at 11:15
  • @Apostolos, Yes, thanks, I think I'm slowly starting to get it.... I found that calling widget.update() was enough to get the real width instead of the puzzling '1'. I'm guessing that tk.update() will refresh all 'out-of-date' widgets (whatever that means..., I read it somewhere..?), while widget.update() does the same for just that widget. I had worried that there was some puzzling change to tk itself, which would be hard to understand. – John White Nov 11 '19 at 16:50
  • yep, future readers please take note of this comment.. it will save a lot of your time debugging as it saved mine!! – dian jin Feb 10 '22 at 02:32
  • Yes, that's true. I took me too a lot ot time to get to that. And this is only **one** of the many things missing from PY documentations! – Apostolos Feb 11 '22 at 12:10
79

Use somewidget.winfo_width() and somewidget.winfo_height() to get the actual widget size, the somewidget['width'] property is only a hint given to the geometry manager.

tzot
  • 92,761
  • 29
  • 141
  • 204
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
  • 1
    I think you mean "geometry manager", instead of "window manager". And thanks! – Denilson Sá Maia Oct 16 '10 at 21:02
  • 1
    As per [this answer](https://stackoverflow.com/questions/28040943/in-tkinter-why-winfo-height-always-return-1) *actual* means after the `mainloop()` call . Which in turn means that if one wants to debug widget sizes, one has to place `print` statements somewhere in the event loop (callbacks) or place the info and read it on some widget like label. That's logical if you think about it, but I guess old procedural habits can kick in regardless. – z33k Feb 08 '18 at 12:52
  • 4
    Don't forget to checkout Apostolos's answer below :) – Michael Harley Jul 17 '18 at 02:44
15

You can use the function somewidget.winfo_reqheight() for height and somewidget.winfo_reqwidth() for width, but first don't forget to call the update function of the widget you want to know the dimension somewidget.update(). If you do not call the update function you will get the default value 1.

  • To add to this, if your `tkinter.Toplevel` parent element (usually produced from `tkinter.Tk()`) is not visible because it was `iconify()`-ed or `withdraw()`-n, you will also just get `1` until you `deiconify()` and `update()` the top window. – David Culbreth Sep 09 '20 at 14:56
  • 2
    On toplevel window, without .update(), and i just use .winfo_reqwidth or .winfo_reqheight() I got the widget size. I use Python 3.9 – KokoEfraim Nov 11 '20 at 08:26