Gtk.Entry 无法通过其他方法 set_text

Gtk.Entry unable to set_text from another method

对 vala 和 Gtk 还很陌生。 我无法调用 Gtk.Entry 的 set_text 方法来从另一个方法设置文本。这是我试过的示例代码。我可以在 activate() 方法中 set_text,但不能通过 tryThis() 方法。

using Gtk;
public class MyApplication : Gtk.Application {

public MyApplication () {
    Object(application_id: "testing.my.application",
    flags: ApplicationFlags.FLAGS_NONE);
}

protected override void activate () {

    Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
    window.set_default_size (800, 600);
    window.window_position = WindowPosition.CENTER;
    window.set_border_width(10);

    Gtk.HeaderBar headerbar = new Gtk.HeaderBar();
    headerbar.show_close_button = true;
    headerbar.title = "Window";
    window.set_titlebar(headerbar);

    //Entry is initialized here
    Gtk.Entry entry = new Gtk.Entry();
    entry.set_text ("Before button click");

    //Button is initialized and connect to method
    Gtk.Button but = new Gtk.Button.with_label("Click me");
    but.clicked.connect(tryThis);

    Gtk.Box vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
    vbox.pack_start(entry, false, false, 10);
    vbox.pack_start(but, false, false, 20);

    window.add(vbox);
    window.show_all ();
}

private void tryThis() {
    Gtk.Entry entry = new Gtk.Entry();
    //This is not working!!
    entry.set_text ("After button click");
    message("%s -", "I am here");
}

public static int main (string[] args) {
    MyApplication app = new MyApplication ();
    return app.run (args);
}

}

问题是范围问题。所以 activate 在该方法的范围内创建一个 entry,而不是整个 class。 tryThis 创建 Gtk.Entry 的新实例并将其分配给该方法范围内的变量 entry,而不是整个 class.

此示例解决了您的问题,但不是最佳解决方案,如示例后所述:

using Gtk;

public class MyApplication : Gtk.Application {

  Gtk.Entry entry;

  public MyApplication () {
    Object(application_id: "testing.my.application",
    flags: ApplicationFlags.FLAGS_NONE);
  }

  protected override void activate () {

  Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
  window.set_default_size (800, 600);
  window.window_position = WindowPosition.CENTER;
  window.set_border_width(10);

  Gtk.HeaderBar headerbar = new Gtk.HeaderBar();
  headerbar.show_close_button = true;
  headerbar.title = "Window";
  window.set_titlebar(headerbar);

  //Entry is initialized here
  entry = new Gtk.Entry();
  entry.set_text ("Before button click");

  //Button is initialized and connect to method
  Gtk.Button but = new Gtk.Button.with_label("Click me");
  but.clicked.connect(tryThis);

  Gtk.Box vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
  vbox.pack_start(entry, false, false, 10);
  vbox.pack_start(but, false, false, 20);

  window.add(vbox);
  window.show_all ();
  }

  private void tryThis() {
    entry.set_text ("After button click");
    message("%s -", "I am here");
  }

  public static int main (string[] args) {
    MyApplication app = new MyApplication ();
    return app.run (args);
  }
}

你应该注意到:

  • entry被带入整个class的范围,在class定义
  • 的开头加上Gtk.Entry entry;
  • entry = new Gtk.Entry (); 已从 tryThis 中删除,因为在调用 activate 时已实例化条目

这可行,但从长远来看,最好将 window 与应用程序分开。例如,使用 activate 来实例化一个新的 MainApplicationWindow。 Vala 还包括 Gtk 模板的代码生成例程。这允许您使用 XML 或 GUI 工具 Glade 定义 window 及其子部件,然后将 Vala 代码附加到 Vala 属性 [GtkTemplate][GtkChild][GtkCallback].