2015-10-31 3 views
0

Я хочу применить определенное поведение к метке. При нажатии боковой кнопки соответствующая метка должна вращаться на 90 градусов. Это можно легко сделать в vala, но я не могу обнаружить конкретного синтаксиса для джинна.Синтаксис Button.connect в Genie

Вала код, который я пытаюсь воспроизвести происходит от элементарной ОС 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 

ответ

2

Проблема связана с тем, где идентификаторы действительны и известны как «область действия».

В примере Vala используется анонимная функция, также называемая лямбда-выражением в Vala. Анонимная функция может быть «закрытием», когда переменные в области, определяющей анонимную функцию, также доступны в анонимной функции. Это полезно, потому что обратный вызов возникает после того, как был запущен исходный блок кода, но переменные все еще доступны в обратном вызове. Таким образом, в примере 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 в пределах класса они становятся доступный для всех функций, определенных в классе. Определения, подобные этому, часто называют «полями». Подчеркивание означает, что они недоступны вне класса, поэтому в примере вы не можете получить к ним доступ от
  • construct() вызывается, когда объект создан, в примере строка new RotatingButtonWindow("Hello World!") создает экземпляр объекта. Если вы повторите строку, у вас будет два отдельных окна, то есть два экземпляра типа данных RotatingButtonWindow
  • Вы заметите, что тип RotatingButtonWindow также определяется как тип Window. Это означает, что он добавляет больше деталей в класс Gtk.Window. Вот почему title и set_border_width() могут быть использованы в новом классе. Они были «в наследство» от родительского класса Gtk.Window
  • При использовании пространства имен Gtk с uses Gtk мы не должны префикс все с Gtk

Как приложение Gtk становится более сложным вы, вероятно, хотите посмотреть на GtkBuilder. Это позволяет отображать окна и виджеты во внешнем файле. Затем используйте GResource для создания файла в двоичном формате вашего приложения, поэтому нет необходимости распространять файл пользовательского интерфейса отдельно.

+0

Я задавался вопросом, существовало ли что-то вроде GResource, что могло бы сделать двоичный код из Css Gtkbuilder. Благодарю. –

Смежные вопросы