簡體   English   中英

如何在Python,GTK3和PyGObject中部署GtkWidget?

[英]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_removegtk_widget_destroy 但我擔心的是:

  1. 考慮gtk_container_remove 它刪除了主機容器的直接子節點。 就我而言,孩子也是許多其他小部件的組合,他們可能互相引用。 是否會刪除直接的孩子,以便處理所有小部件?

  2. 考慮gtk_widget_destroy 它是遞歸的,似乎是我需要的,但也似乎太殘酷了。 這是否真的需要手動銷毀小部件? 將這份工作留給參考櫃台會更好嗎?

我願意聽到這個案子的“最佳做法”。

最佳做法是永遠不要依賴垃圾收集器來收集及時控制有限資源的對象。 它可以無限期地延遲收集任何特定的垃圾。 您不希望為垃圾收集器打開文件以進行清理,因為您可以立即打開的文件句柄數量有限制。

碰巧Python的垃圾收集器有一個引用計數器,並且會立即釋放沒有引用的對象,但這是一個實現細節。 如果您使用其他實現,例如PyPy或IronPython,則不適用。 當我將它移動到另一個實現時,我有一個程序中斷,因為我無意中依賴Python的引用計數來清理資源。 此外,您最終可能會因為意外在某處創建循環而發生錯誤。

我不知道具體的小部件的任何最佳實踐。 我沒有考慮過我應該清理它們的可能性。 如果一個小部件有一個與之關聯的窗口,那么理論上應該清理一個OS句柄。 通常,只有GtkWindow會有一個真實的窗口,但是你的插件可能會創建一個帶窗口的窗口小部件。 所以,我會說,在一個特定的不太可能的情況下,你理論上應該銷毀小部件。 否則,如果你不需要它們,可以手動銷毀它們,但我會說不要這么做。

從我的觀點來看,你可以使用其中任何一種,因為會發生的是:

  1. 當您使用gtk_container_remove時 ,如果您的子對象(self.guest)沒有其他引用,那么它將被自動銷毀。 我的意思是GtkContainer將減少引用計數, GObject系統將調用gtk_widget_destroy。
  2. 如果你調用gtk_widget_destroy ,那確實會破壞小部件,並且在此過程中將從其父級釋放小部件。

所以,你可以使用其中任何一個,但我將使用第一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM