28

How do you show and hide widgets in Tkinter? I want to have an entry box, but not have it shown at all times. Can someone show me the functions to show and hide entry widgets and other widgets in tkinter? I want to be able to do this without having multiple frames.

udpatil
  • 529
  • 2
  • 6
  • 14
  • 3
    I think, there's the answer to your question - http://stackoverflow.com/questions/3819354/in-tkinter-is-there-any-way-to-make-a-widget-not-visable – mega.venik Apr 22 '12 at 11:29

2 Answers2

40

This has been answered before on stackoverflow. The short answer is, you can use grid_remove which will cause the widget to be removed if it was previously added via grid. grid_remove remembers where the widget was, so a simple grid() will put it back without having to re-specify all of the options.

You can also use pack_forget (if using pack) and grid_forget (if using grid). These work similarly to grid_remove except they cause all of the settings to be forgotten, which means you have to explicitly place it back into the proper place on the screen.

Another option is to take advantage of the stacking order of widgets. You can use the lower method to hide the widget behind its sibling, and lift to raise it above. See this answer for an example.

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 1
    Do you know any caveats to this, offhand? In Python 3.x, if I use grid_remove, the widget removes as expected, but grid doesn't make it return (visibly, anyhow, if it does). I'm wondering if I need to do some complicated stuff with columnconfigure to get it to show. – Brōtsyorfuzthrāx Aug 18 '18 at 04:23
  • Huh. Apparently, if I just add the original arguments to grid it works in restoring it (good enough for me, although I don't know why it didn't work without it): grid(columnspan=4, sticky=E+W+S) – Brōtsyorfuzthrāx Aug 18 '18 at 04:30
7

I tried the suggestions that others have posted and noticed that I was making a simple mistake. You can't call .grid() on the same line that you declare the widget that you're going to hide.

To clarify, I previously had this:

self.helpExpansion = ttk.Label(self.helpMenu, text="Expansion Widget").grid(row=1, column=3, sticky=EW)
self.helpExpansion.grid_remove()

But I got the error AttributeError: 'NoneType' object has no attribute 'grid_remove'. To fix it, I had to make the call to .grid() on a new line, like this:

self.helpExpansion = ttk.Label(self.helpMenu, text="Help Expansion")
self.helpExpansion.grid(row=1, column=3, sticky=EW)
self.helpExpansion.grid_remove()

Then to toggle between showing and hiding, I just alternated between calling self.helpExpansion.grid() (function arguments not needed) and self.helpExpansion.grid_remove().

For me it worked with both tk.Label or ttk.Label. I'm using Python 2.7.13. Hope that helps!

Olivia Stork
  • 4,660
  • 5
  • 27
  • 40
  • 4
    The reason for this is that instead of assigning the Label reference to self.helpExpansion you are actually assigning the return value of the call to grid(), which returns None. Adding the call to grid() onto the call to a widget constructor is a convenient shorthand, but only if you don't need a reference to that widget later (such as a fixed label, or when you interact with the widget through one of the special tk variables or through a callback). – DrEsperanto Mar 09 '18 at 23:22
  • The mistake you made is actually fairly common, see [Tkinter: AttributeError: NoneType object has no attribute ](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name). – martineau May 01 '22 at 19:49