4

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。しかし、私は心配しています:

  1. 考えてみてくださいgtk_container_remove。ホストコンテナの直接の子を削除します。私の場合、子は他の多くのウィジェットの構成でもあり、それらは相互に参照している可能性があります。すべてのウィジェットを破棄するのに十分な直接の子を削除しますか?

  2. 考えてみてくださいgtk_widget_destroy。それは再帰的で、私が必要としているもののように見えますが、あまりにも残忍なようです。これはウィジェットを手動で破棄するために本当に必要ですか?その仕事を参照カウンターに任せたほうがいいでしょうか?

この場合の「ベストプラクティス」を喜んで聞きます。

4

2 に答える 2

2

ベストプラクティスは、限られたリソースをタイムリーに制御するオブジェクトを収集するためにガベージコレクターに依存しないことです。特定のガベージの収集が無期限に遅れる可能性があります。一度に開くことができるファイルハンドルの数には制限があるため、ガベージコレクターがクリーンアップするためにファイルを開いたままにしないでください。

Pythonのガベージコレクターには参照カウンターがあり、参照のないオブジェクトをすぐに解放することがありますが、これは実装の詳細です。PyPyやIronPythonなどの別の実装を使用する場合、これは適用されません。別の実装に移動したときにプログラムが中断しました。これは、リソースをクリーンアップするためにPythonの参照カウントに誤って依存していたためです。また、誤ってどこかでサイクルを作成したために発生するバグが発生する可能性があります。

特にウィジェットのベストプラクティスはわかりません。私はそれらを片付ける必要がある可能性を考えていませんでした。ウィジェットにウィンドウが関連付けられている場合、それは理論的にクリーンアップする必要があるOSハンドルです。通常、GtkWindowのみが実際のウィンドウを持ちますが、プラグインがウィンドウを備えたウィジェットを作成することは可能です。したがって、その1つの特定のありそうもないケースでは、理論的にはウィジェットを破棄する必要があります。それ以外の場合は、必要がなければ手動で破棄しても問題ありませんが、邪魔にならないようにしてください。

于 2012-03-26T01:01:29.340 に答える
1

私のポイントから、あなたはそれらのどれでも使うことができます、なぜなら何が起こるかはこれです:

  1. gtk_container_removeを使用するときに、子オブジェクト(self.guest)に他の参照がない場合は、自動的に破棄されます。つまり、 GtkContainerは参照カウントを減らし、GObjectシステムはgtk_widget_destroyを呼び出します。
  2. gtk_widget_destroyを呼び出すと、それは実際にウィジェットを破壊し、その過程でウィジェットをその親から解放します。

だから、あなたはそれらのどれでも使うことができます、しかし私は最初のものを使います。

于 2012-03-26T13:32:46.630 に答える