1

我试图弄清楚为什么我的代码在从静态 main 函数第一次调用时输出“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

信号连接有问题吗?

4

1 回答 1

3

Vala 不能为由自动 GtkBuilder 连接的回调提供类型安全,因此您必须小心提供正确的定义。请参阅Vala wiki 上 GTK+ 示例的从 XML 文件加载用户界面部分。具体来说,这部分:

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

所以你的方法应该是:

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

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

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

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

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

[CCode (instance_pos = -1)]
public void step_clicked (Gtk.Button button) {
  stderr.printf("%d\n", pc);          
}
于 2013-05-04T00:58:48.703 回答