How do I restore a destroyed widget in tkinter? - python

def change_section_to_main():
SUB_SECTION.destroy()
APP_MAIN_FRAME.pack()
I want to restore the widget "APP_MAIN_FRAME". I thought I could do it with pack() turns out I was wrong. I keep getting this Error >>
_tkinter.TclError: bad window path name ".!frame

You can't "undestroy" a widget. Once it has been destroyed it can no longer be used.
Usually, the solution to this specific problem is to hide the widget rather than destroy it. You can hide it by using one of pack_forget, grid_forget, grid_remove or place_forget depending on exactly what you want to have happen and on which tool (pack, grid, or place) that you used to add it to the window.
If you expect to hide and show a widget often, grid is the best choice since grid_remove will remember how the item was placed. A subsequent call to grid() with no arguments will restore all of the settings. pack and place do not remember the configuration of a widget when it is forgotten.

Related

Can we delete the label and repack it during second time code runs PYTHON

if bool(suggestion_label.winfo_ismapped()):
suggestion_label.destroy()
else:
suggestion_label.pack()
I wanted to ask that anything i do the label packs on the screen and its not deleted second time PART of the code runs.
If you call destroy on a widget, it's gone and can't be used again.
If you want to hide and reveal it, use pack_forget instead of destroy. Be aware that pack is dependent on the order it's called. Re-packing the widget may not put it back in the same place unless you explicitly use the before or after options.
If you use grid, it has a grid_remove function where it will remember where it was replaced. Calling grid with no arguments will restore it with the same grid settings.

Clear whole root

I am new to tkinter and I was wondering if there is a way to clear whole root (window). I tried with root.destroy() , but I want to have a chance to undo(to callback some widgets). I also tried .pack_forget() and .grid_forget() , but it takes a lot of time and later may cause many bugs in program.
Thank you for help.
If you plan on literally destroying everything in the root window, my recommendation is to make a single frame be a child of the root window, and then put everything inside that frame. Then, when you need to clear the root window you only have to delete this one widget, and it will take care of deleting all of the other widgets.
If instead of destroying the widgets you want to merely hide them, the best solution is to use grid, so that you can use grid_forget to remove them from view, and grid to make them visible again. You can use pack and pack_forget, but pack doesn't remember where the widget was, making it more difficult to restore them without a lot of work.
If your program is made of logical groups of widgets, use frames to create the groups, and then you can destroy or call grid_forget on the entire frame at once, rather than having to do that for each individual widget.
for ele in root.winfo_children():
ele.destroy()

pyGTK : pack and unpack

Can I use pack once the main loop has been showed, or should I use something else to add /remove widgets to /from a vbox afterwards ?
I have this gtk.Window() that contains a vbox, where a menu, a treeview and a button are packed. At the push of this button, I want to display an image in a new container inside this window / vbox, and ideally, close said container at will.
(think image viewer with a file list, you click on an image file and a pane opens displaying it, if you click on another image file the new image is displayed in place of the old, and you can close the image pane)
My question is : How do you do that ? My trials so far led me to believe that once the vbox has been show()'d, you cant pack anything else into it..?
Has the "image" container have to exist prior to being displayed...?
What is the proper process to do this, in witch direction of the GTK manual should I look?
In GTK+ all widgets are hidden by default (which I think was a stupid design decision, but oh well). You usually call show_all() on a window, so indirectly show all widgets contained in it by the time of the call. If you add (pack, whatever) a widget later, don't forget to show() it manually.

Assiociate Widgets into Groups, for Hide and Show, wxpython

I have a bunch of widgets and right now I am using Hide() and Show() to each widget individually when I flip through different sections/pages of my program.
Because I did this, You can see each widget leaving/showing one by one (which kinda sucks).
Is there anyway to group all these widgets and then be able to Hide() and Show() this group, to avoid this "one by one" habit?
Try using Freeze/Thaw/Layout when you are showing and hiding the widgets. This way they should all appear/disappear at the same time.
Put your group of widgets organized in a sizer in the same parent container (p.e. a panel) and hide the parent. All the widgets disappear with the parent.
Note that sometimes hiding (for example) buttons or checkboxes is not the best solution. Available functionality for the user can be also modulated using widget.Disable()

How do I prevent Qt buttons from appearing in a separate frame?

I'm working on a PyQt application. Currently, there's a status panel (defined as a QWidget) which contains a QHBoxLayout. This layout is frequently updated with QPushButtons created by another portion of the application.
Whenever the buttons which appear need to change (which is rather frequently) an update effect gets called. The existing buttons are deleted from the layout (by calling layout.removeWidget(button) and then button.setParent(None)) and the new buttons are added to the layout.
Generally, this works. But occasionally, when I call button.setParent(None) on the button to delete, it causes it to pop out of the application and start floating in its own stand-alone frame.
How can I remove a button from the layout and ensure it doesn't start floating?
You should call the button's close() method. If you want it to be deleted when you close it, you can set the Qt.WA_DeleteOnClose attribute:
button.setAttribute(Qt.WA_DeleteOnClose)
Try calling QWidget::hide() on the button before removing from the layout if you don't want to delete your button.

Categories

Resources