我的信号处理程序出了什么问题?

时间:2013-05-03 22:07:03

标签: callback gtk vala

我试图弄清楚为什么我的代码在静态主函数的第一次调用中输出“1”,而在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>

我正在使用此命令行进行编译:

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

信号连接有问题吗?

1 个答案:

答案 0 :(得分:3)

Vala无法为通过automaticGtkBuilder连接的回调提供类型安全性,因此您必须小心提供正确的定义。请参阅Vala wiki上GTK +示例的Loading User Interface from XML File部分。具体来说,这部分:

  

注意:使用Gtk.Builder的信号自动连接功能时,所有处理程序必须具有相应信号的完整签名,包括信号发送方作为第一个参数。否则,您将在运行时遇到分段错误。

所以你的方法应该是:

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

如果你愿意,你可以使按钮参数为空,这样你仍然可以通过传递null来从main()调用它。

但是,实例仍然在错误的位置,正如在该链接中所解释的那样:

  

如果希望回调方法是实例方法而不是静态方法,则必须使用[CCode(instance_pos = -1)]属性对它们进行注释,并将实例传递给connect_signals(...)而不是null:< / p>

您正在将实例传递给connect_signals,但您缺少CCode注释。所以你真正想要的是:

[CCode (instance_pos = -1)]
public void step_clicked (Gtk.Button button) {
  stderr.printf("%d\n", pc);          
}