How to remove GtkWidget in Python, GTK3 and PyGObject?

I am creating a plug-in for the GTK3 program. This plugin can be turned on or off at runtime. When it is turned on, it should fill in its GUI in the specified area (GtkBin) in the main program. When it is disconnected, it should be removed from this area.

This simple program shows the use of:

#!/usr/bin/python2 from gi.repository import Gtk window = Gtk.Window() class Plugin(object): def __init__(self, host): assert(isinstance(host, Gtk.Bin)) self.host = host self.guest = None def enable(self): box = Gtk.Box(orientation = Gtk.Orientation.VERTICAL) for x in range(10): box.add(Gtk.Button("Button {}".format(x))) self.guest = box self.host.add(self.guest) def disable(self): self.host.remove(self.guest) # self.guest.destroy() # is this better? self.guest = None plugin = Plugin(window) plugin.enable() #plugin.disable() window.connect("destroy", Gtk.main_quit) window.show_all() Gtk.main() 

I want that when disconnecting the plug-in, all widgets added to the host should be placed correctly.

I found this question very similar: Free object / widget in GTK? He suggested gtk_container_remove and gtk_widget_destroy . But I am worried:

  • Consider gtk_container_remove . It removes the direct child of the host container. In my case, the child is also an integral part of many other widgets, and they can refer to each other. Will the direct child remove all widgets that will be deleted?

  • Consider gtk_widget_destroy . It is recursive and seems to me what I need, but also seems too cruel. Is it really necessary to manually destroy the widget? Would it be better to leave this work on the control counter?

I am ready to hear the "best practice" for this occasion.

+4
source share
2 answers

It is best practice to never rely on a garbage collector to collect an object that monitors a limited resource in a timely manner. This may delay the collection of any particular garbage indefinitely. You do not want to leave the file open for the garbage collector to clean up, because there is a limit to the number of files that you can open right away.

It happens that the Python garbage collector has a reference counter and frees objects without links for free, but this is a detail of the implementation. If you use another implementation, such as PyPy or IronPython, this does not apply. I had a break in the program when I moved it to another implementation because I inadvertently relied on counting Python links to clean up resources. In addition, you may encounter errors that occur because you accidentally created a loop somewhere.

I do not know any best practices for widgets. I did not think that I should clean them. If the widget has a window associated with it, this is an OS handle that you should theoretically clean up. Usually only GtkWindow will have a real window, but it is possible that your plugin will create a widget with a window. So, I would say that in this particular unlikely event, you should theoretically destroy the widget. Otherwise, it is great to destroy them manually if you do not need them, but I would say do not do this to do this.

+2
source

From my point of view, you can use any of them, as this will happen:

  • When you use gtk_container_remove , if your child (self.guest) has no other reference, it will be destroyed automatically. I mean that GtkContainer will decrease the reference count, and the GObject system will call gtk_widget_destroy.
  • If you call gtk_widget_destroy , it will really destroy the widget, and in this process the widget will be released from its parent.

So, you can use any of them, but I will use the first.

+1
source

Source: https://habr.com/ru/post/1403325/


All Articles