0

私はvalaクラスでこれの振る舞いを扱うのにほとんど問題がありません。

これが私のコードです:(build_and_send1とbuild_and_send2はボタンを押すことによって発生するシグナルです)

using GLib;
using Gtk;

public class Main : Object 
{

    /* 
     * Uncomment this line when you are done testing and building a tarball
     * or installing
     */
    //const string UI_FILE = Config.PACKAGE_DATA_DIR + "/" + "gtk_httpclient.ui";
    const string UI_FILE = "src/gtk_httpclient.ui";

    /* ANJUTA: Widgets declaration for gtk_httpclient.ui - DO NOT REMOVE */


    private Builder builder;

    public Main ()
    {

        try 
        {
            this.builder = new Builder ();
            this.builder.add_from_file (UI_FILE);
            this.builder.connect_signals (this);

            var window = this.builder.get_object ("window") as Window;
            /* ANJUTA: Widgets initialization for gtk_httpclient.ui - DO NOT REMOVE */
            window.show_all ();

            stderr.printf ("constructor:\n");
            stderr.printf ("this: %p\n", this);
            stderr.printf ("builder: %p\n", this.builder);
        } 
        catch (Error e) {
            stderr.printf ("Could not load UI: %s\n", e.message);
        } 

    }

    [CCode (instance_pos = -1)]
    public void on_destroy (Widget window) 
    {
        Gtk.main_quit();
    }

    public void build_and_send1 (Widget button)
    {
        stderr.printf ("\nbuild_and_send1:\n");
        stderr.printf ("this: %p\n", this);
        stderr.printf ("builder: %p\n", this.builder);
    }

    [CCode (instance_pos = -1)]
    public void build_and_send2 (Widget button)
    {
        stderr.printf ("\nbuild_and_send2:\n");
        stderr.printf ("this: %p\n", this);
        stderr.printf ("builder: %p\n", this.builder);
    }

    static int main (string[] args) 
    {
        Gtk.init (ref args);
        new Main ();

        Gtk.main ();

        return 0;
    }
}

私はこの出力を持っています:

constructor:
this: 0x1a524a0
builder: 0x1a6a230

build_and_send1:
this: 0x1aa2030
builder: 0x5a4fe823

build_and_send2:
this: 0x1a524a0
Program has been terminated receiving signal 11 (Segmentation fault)

シグナルにMainの同じインスタンスが必要な場合は、その前に[CCode(instance_pos = -1)]を付ける必要があると思います。しかし、builder.connect_signals(this)の目標は何ですか。

そして、なぜthis.builderはコンストラクターではなくbuild_and_send2でセグメンテーション違反を起こすのですか?

4

2 に答える 2

0

おそらく、その結果は、new Main()建設後に範囲外になり、ガベージコレクションされます。それを変数に割り当てます。

于 2013-03-26T21:51:59.623 に答える
0

私はこれがどのように機能しているかをもう少し理解しています。

私のプロジェクトでは、UIイベントを処理するためのUIHandlerクラスを作成しました。

このクラスのインスタンスをコンストラクター内で接続すると機能しませんが、クラス外でインスタンスを接続すると正常に機能します。

間違った例:これはセグメンテーション違反で終了します。

// Constructor
public UIHandler (Builder builder) {
    var button = builder.get_object ("send-button") as Button;
    Object (button: button);

    bulder.connect_signals (this);
}
...
[CCode (instance_pos = -1)]
public void activate (Entry location) {
    this.button.clicked ();
}

正解:これは問題になります。

メインクラス:

public Main ()
{

    try 
    {
        var builder = new Builder ();
        builder.add_from_file (UI_FILE);

        builder.connect_signals (new UIHandler (builder));

        var window = builder.get_object ("window") as Window;

        /* ANJUTA: Widgets initialization for gtk_http_client.ui - DO NOT REMOVE */
        window.show_all ();
    } 
    catch (Error e) {
        stderr.printf ("Could not load UI: %s\n", e.message);
    } 

}

UIHandlerクラス:

// Constructor
public UIHandler (Builder builder) {
    var button = builder.get_object ("send-button") as Button;
    Object (button: button);
}
...
[CCode (instance_pos = -1)]
public void activate (Entry location) {
    this.button.clicked ();
}

この振る舞いは私の元の問題を解決します。

于 2013-04-24T10:36:53.670 に答える