Genie中的Button.connect语法

时间:2015-10-31 09:04:26

标签: linux gtk3 genie

我想将某种行为应用于标签。单击横向按钮时,相应的标签应旋转90度。它可以在vala中轻松完成,但我无法发现精灵的特定语法。

我试图重现的vala代码来自基本操作系统getting started guide

hello_button.clicked.connect(() =>
{ 
hello_label.label = "Hello World!";
hello_button.sensitive = false;
});


rotate_button.clicked.connect(() =>
{ 
rotate_label.angle = 90;
rotate_label.label = "Verbal";
rotate_button.sensitive = false;
});

我实际上设法几乎完全复制了Genie中的代码,但轮换除外。这是我有多远:

/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
**   compile with valac --pkg gtk+03.0 layoutgtkexample.gs */

[indent=4]
uses Gtk

init
    Gtk.init (ref args)
    var window = new Gtk.Window()
    window.title = "Hello World!"
    window.set_border_width(12)

    var layout = new Gtk.Grid ()
    layout.column_spacing = 6
    layout.row_spacing = 6

    var hello_button = new Gtk.Button.with_label("Say Hello")
    var hello_label = new Gtk.Label("Hello")

    var rotate_button = new Gtk.Button.with_label ("Rotate")
    var rotate_label = new Gtk.Label("Horizontal")

    // add first row of widgets

    layout.attach (hello_button, 0, 0, 1,1)
    layout.attach_next_to (hello_label, hello_button, PositionType.RIGHT, 1, 1)

    // add second row of widgets

    layout.attach(rotate_button, 0,1,1,1)
    layout.attach_next_to(rotate_label, rotate_button, PositionType.RIGHT, 1, 1)

    window.add(layout)

    hello_button.clicked.connect(hello_pushed)
    rotate_button.clicked.connect(rotate_pushed)

    window.destroy.connect(Gtk.main_quit)
    window.show_all ()
    Gtk.main ()

def hello_pushed (btn:Button)
    btn.label = "Hello World!"
    btn.sensitive = false

def rotate_pushed (btn:Button)
    btn.label = "Vertical"
    //btn.angle = 90
    btn.sensitive = false

1 个答案:

答案 0 :(得分:3)

问题在于标识符的有效位置,并称为“范围”。

Vala示例使用匿名函数,在Vala中也称为lambda表达式。当定义匿名函数的作用域中的变量在匿名函数中也可用时,匿名函数可以是“闭包”。这很有用,因为回调发生在原始代码块运行之后,但变量在回调中仍然可用。因此,在Vala示例中,按钮和标签都在封闭范围内定义,按钮和标签也可以在回调匿名函数中使用。

不幸的是,Genie无法将匿名函数解析为函数参数,在本例中是connect()调用。虽然some work has been done on this in 2015。所以你正确地使用了一个函数名。问题是回调只将按钮作为参数传递而不是相邻的标签。因此,为了在回调函数中使标签可用,我们可以使用类:

/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
**   compile with valac --pkg gtk+-3.0 layoutgtkexample.gs */

[indent=4]
uses Gtk

init
    Gtk.init (ref args)
    new RotatingButtonWindow( "Hello World!" )
    Gtk.main ()

class RotatingButtonWindow:Window
    _hello_label:Label
    _rotate_label:Label

    construct( window_title:string )
        title = window_title
        set_border_width(12)

        var layout = new Grid ()
        layout.column_spacing = 6
        layout.row_spacing = 6

        // add 'hello' row of widgets
        var hello_button = new Button.with_label("Say Hello")
        _hello_label = new Label("Hello")
        layout.attach (hello_button, 0, 0, 1,1)
        layout.attach_next_to (_hello_label, hello_button, PositionType.RIGHT, 1, 1)

        // add 'rotate' row of widgets
        var rotate_button = new Button.with_label ("Rotate")
        _rotate_label = new Label("Horizontal")
        layout.attach(rotate_button, 0,1,1,1)
        layout.attach_next_to(_rotate_label, rotate_button, PositionType.RIGHT, 1, 1)

        add(layout)

        hello_button.clicked.connect(hello_pushed)
        rotate_button.clicked.connect(rotate_pushed)

        destroy.connect(Gtk.main_quit)
        show_all ()

    def hello_pushed (btn:Button)
        _hello_label.label = "Hello World!"
        btn.sensitive = false

    def rotate_pushed (btn:Button)
        _rotate_label.label = "Vertical"
        _rotate_label.angle = 90
        btn.sensitive = false

一些注意事项:

  • 通过将_hello_label_rotate_label的定义放在类的范围内,它们可用于类中定义的所有函数。像这样的定义通常称为“字段”。下划线表示它们在课堂外不可用,因此在示例中,您无法从init
  • 访问它们 在创建对象时调用
  • construct(),在示例中,行new RotatingButtonWindow( "Hello World!" )实例化对象。如果重复该行,您将有两个单独的窗口,即RotatingButtonWindow数据类型的两个实例
  • 您会注意到RotatingButtonWindow类型也定义为Window类型。这意味着它正在向Gtk.Window类添加更多细节。这就是为什么titleset_border_width()可以在新类中使用的原因。它们已从父Gtk.Window
  • “继承”
  • 通过uses Gtk使用Gtk名称空间,我们无需使用Gtk
  • 作为前缀

随着您的Gtk应用程序变得更加复杂,您可能希望查看GtkBuilder。这允许窗口和小部件布局在外部文件中。然后使用GResource将文件构建到应用程序的二进制文件中,这样就不需要单独分发UI文件。