[英]How to dispose GtkWidget's in Python, GTK3 and PyGObject?
我正在为GTK3程序创建一个插件。 可以在运行时启用或禁用此插件。 启用后,它应在主程序中的给定区域(GtkBin)中填充其GUI。 禁用时,它应该从该区域中删除。
这个简单的程序描述了用法:
#!/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()
我希望在禁用插件时,应该正确处理它添加到主机的所有小部件。
我发现这个问题非常相似: GTK中的免费对象/小部件? 它提出了gtk_container_remove
和gtk_widget_destroy
。 但我担心的是:
考虑gtk_container_remove
。 它删除了主机容器的直接子节点。 就我而言,孩子也是许多其他小部件的组合,他们可能互相引用。 是否会删除直接的孩子,以便处理所有小部件?
考虑gtk_widget_destroy
。 它是递归的,似乎是我需要的,但也似乎太残酷了。 这是否真的需要手动销毁小部件? 将这份工作留给参考柜台会更好吗?
我愿意听到这个案子的“最佳做法”。
最佳做法是永远不要依赖垃圾收集器来收集及时控制有限资源的对象。 它可以无限期地延迟收集任何特定的垃圾。 您不希望为垃圾收集器打开文件以进行清理,因为您可以立即打开的文件句柄数量有限制。
碰巧Python的垃圾收集器有一个引用计数器,并且会立即释放没有引用的对象,但这是一个实现细节。 如果您使用其他实现,例如PyPy或IronPython,则不适用。 当我将它移动到另一个实现时,我有一个程序中断,因为我无意中依赖Python的引用计数来清理资源。 此外,您最终可能会因为意外在某处创建循环而发生错误。
我不知道具体的小部件的任何最佳实践。 我没有考虑过我应该清理它们的可能性。 如果一个小部件有一个与之关联的窗口,那么理论上应该清理一个OS句柄。 通常,只有GtkWindow会有一个真实的窗口,但是你的插件可能会创建一个带窗口的窗口小部件。 所以,我会说,在一个特定的不太可能的情况下,你理论上应该销毁小部件。 否则,如果你不需要它们,可以手动销毁它们,但我会说不要这么做。
从我的观点来看,你可以使用其中任何一种,因为会发生的是:
所以,你可以使用其中任何一个,但我将使用第一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.