Genie中的Button.connect语法 [英] The Button.connect syntax in Genie

查看:90
本文介绍了Genie中的Button.connect语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对标签应用某种行为.单击侧面按钮时,相应的标签应旋转90度.可以很轻松地在vala中完成此操作,但是我找不到关于genie的特定语法.

I want to apply a certain behaviour to a label. When a lateral button is clicked, the corresponding label should rotate 90 degrees. It can be easily done in vala, but I can't discover the particular syntax on genie.

我要复制的vala代码来自基本操作系统入门指南:

The vala code I am trying to reproduce comes from elementary OS 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中的代码.这是我走的距离:

I actually managed to reproduce almost entirely the code in Genie, for the exception of the rotation. Here is how far I got:

/* 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

推荐答案

问题与标识符有效且被称为作用域"的地方有关.

The problem is to do with where identifiers are valid and is known as "scope".

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

The Vala example makes use of an anonymous function, also called a lambda expression in Vala. An anonymous function can be a "closure", when the variables in the scope that defines the anonymous function are also available within the anonymous function. This is useful because the callback occurs after the original block of code has been run, but the variables are still available within the callback. So in the Vala example, where both the button and label are defined in the enclosing scope, the button and label are also available in the callback anonymous function.

不幸的是,Genie无法将匿名函数解析为函数参数,在这种情况下,是在connect()调用中.尽管在2015年已经完成了一些工作.因此,您正确地使用了函数名称.问题是回调仅将按钮作为参数传递,而不将相邻标签作为参数传递.因此,为了使标签在回调函数中可用,我们可以使用一个类:

Unfortunately Genie isn't able to parse anonymous functions as function arguments, in this case within the connect() call. Although some work has been done on this in 2015. So you have rightly used a function name instead. The problem is the callback only passes the button as an argument and not the adjacent label. So to make the label available within the callback function we could use a class:

/* 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
  • By placing the definitions of the _hello_label and _rotate_label within the scope of the class they become available to all the functions defined in the class. Definitions like this are often called "fields". The underscore means they are not available outside the class, so in the example you cannot access them from init
  • construct() is called when the object is created, in the example the line new RotatingButtonWindow( "Hello World!" ) instantiates the object. If you repeat the line you will have two separate windows, that is two instances of the RotatingButtonWindow data type
  • You will notice that the RotatingButtonWindow type is also defined as a Window type. This means it is adding more detail to the Gtk.Window class. This is why title and set_border_width() can be used within the new class. They have been "inherited" from the parent Gtk.Window class
  • By using the Gtk namespace with uses Gtk we don't need to prefix everything with Gtk

随着您的Gtk应用程序变得越来越复杂,您可能想看看GtkBuilder.这样就可以将窗口和小部件布置在外部文件中.然后使用GResource将文件构建到应用程序的二进制文件中,因此无需单独分发UI文件.

As your Gtk application gets more complex you probably want to look at GtkBuilder. That allows windows and widgets to be laid out in an external file. Then use GResource to build the file into the binary of your application so there is no need to distribute the UI file separately.

这篇关于Genie中的Button.connect语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆