Question

I'm trying to figure out why my code outputs "1" on the first invocation from the static main function and some apparently random value on subsequent calls from a Gtk.Button.

gtkdream.vala:

using GLib;
using Gtk;

public class Main : Object {
    public int pc = 1;

    public Main () {
        var builder = new Builder ();
        builder.add_from_file ("gtkdream.ui");
        builder.connect_signals (this);
        var window = builder.get_object ("window") as Window;
        window.show_all ();
    }

    public void step_clicked () {
        stderr.printf("%d\n", pc);          
    }

    static int main (string[] args) {
        Gtk.init (ref args);
        var app = new Main ();
        app.step_clicked ();
        Gtk.main ();
        return 0;
    }
}

gtkdream.ui:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkWindow" id="window">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">window</property>
    <property name="window_position">center</property>
    <property name="default_width">500</property>
    <property name="default_height">400</property>
    <child>
      <object class="GtkButton" id="step">
        <property name="use_action_appearance">False</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="use_action_appearance">False</property>
        <property name="label" translatable="yes">Schritt ausführen</property>
        <property name="use_underline">True</property>
        <signal name="clicked" handler="main_step_clicked" swapped="no"/>
      </object>
    </child>
  </object>
</interface>

I'm using this command line to compile it:

valac gtkdream.vala --pkg gtk+-3.0 --pkg gmodule-2.0

Is something wrong with the signal connection?

Was it helpful?

Solution

Vala cannot provide type safety for callbacks which are connected by automaticallyGtkBuilder, so you have to be careful to provide the correct definition. See the Loading User Interface from XML File section of the GTK+ samples on the Vala wiki. Specifically, this part:

Attention: When using Gtk.Builder's signal auto-connection feature all handlers must have the full signatures of their corresponding signals, including the signal sender as first parameter. Otherwise you will get segmentation faults at runtime.

So your method should be:

public void step_clicked (Gtk.Button button) {
  stderr.printf("%d\n", pc);          
}

You can make the button parameter nullable if you want so you can still invoke it from main() by passing null.

However, the instance is still in the wrong place, as is also explained in that link:

If you want the callback methods to be instance methods instead of static methods you have to annotate them with the [CCode(instance_pos=-1)] attribute and pass the instance to connect_signals(...) instead of null:

You're passing the instance to connect_signals, but you're missing the CCode annotation. So really what you want is:

[CCode (instance_pos = -1)]
public void step_clicked (Gtk.Button button) {
  stderr.printf("%d\n", pc);          
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top