Genie 中的 Button.connect 语法
The Button.connect syntax in Genie
我想将特定行为应用于标签。单击横向按钮时,相应的标签应旋转 90 度。在 vala 中可以很容易地完成,但我无法在 genie 上找到特定的语法。
我试图重现的 vala 代码来自 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 中的几乎整个代码,除了旋转之外。这是我的进展:
/* 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
问题与标识符的有效位置有关,称为 "scope"。
Vala 示例使用匿名函数,在 Vala 中也称为 lambda 表达式。当定义匿名函数的范围内的变量在匿名函数内也可用时,匿名函数可以是 "closure"。这很有用,因为回调发生在原始代码块 运行 之后,但变量在回调中仍然可用。因此,在 Vala 示例中,按钮和标签都在封闭范围内定义,按钮和标签在回调匿名函数中也可用。
不幸的是,Genie 无法将匿名函数解析为函数参数,在本例中是在 connect()
调用中。虽然some work has been done on this in 2015。所以你正确地使用了一个函数名。问题是回调只将按钮作为参数传递,而不是相邻的标签。因此,为了使标签在回调函数中可用,我们可以使用 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
的定义置于 class 的范围内,它们可用于 class 中定义的所有函数。像这样的定义通常称为 "fields"。下划线表示它们在 class 之外不可用,因此在示例中您无法从 init
访问它们
construct()
在创建 object 时调用,在示例中,行 new RotatingButtonWindow( "Hello World!" )
实例化了 object。如果重复该行,您将有两个单独的 windows,即 RotatingButtonWindow
数据类型 的两个实例
- 您会注意到
RotatingButtonWindow
类型也被定义为 Window
类型。这意味着它正在向 Gtk.Window
class 添加更多详细信息。这就是 title
和 set_border_width()
可以在新的 class 中使用的原因。他们已经 "inherited" 从 parent Gtk.Window
class
- 通过使用带有
uses Gtk
的 Gtk 命名空间,我们不需要在所有内容前加上 Gtk
随着您的 Gtk 应用程序变得越来越复杂,您可能想要查看 GtkBuilder
。这允许 windows 和小部件放置在外部文件中。然后使用 GResource
将文件构建到应用程序的二进制文件中,这样就无需单独分发 UI 文件。
我想将特定行为应用于标签。单击横向按钮时,相应的标签应旋转 90 度。在 vala 中可以很容易地完成,但我无法在 genie 上找到特定的语法。
我试图重现的 vala 代码来自 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 中的几乎整个代码,除了旋转之外。这是我的进展:
/* 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
问题与标识符的有效位置有关,称为 "scope"。
Vala 示例使用匿名函数,在 Vala 中也称为 lambda 表达式。当定义匿名函数的范围内的变量在匿名函数内也可用时,匿名函数可以是 "closure"。这很有用,因为回调发生在原始代码块 运行 之后,但变量在回调中仍然可用。因此,在 Vala 示例中,按钮和标签都在封闭范围内定义,按钮和标签在回调匿名函数中也可用。
不幸的是,Genie 无法将匿名函数解析为函数参数,在本例中是在 connect()
调用中。虽然some work has been done on this in 2015。所以你正确地使用了一个函数名。问题是回调只将按钮作为参数传递,而不是相邻的标签。因此,为了使标签在回调函数中可用,我们可以使用 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
的定义置于 class 的范围内,它们可用于 class 中定义的所有函数。像这样的定义通常称为 "fields"。下划线表示它们在 class 之外不可用,因此在示例中您无法从init
访问它们
construct()
在创建 object 时调用,在示例中,行new RotatingButtonWindow( "Hello World!" )
实例化了 object。如果重复该行,您将有两个单独的 windows,即RotatingButtonWindow
数据类型 的两个实例
- 您会注意到
RotatingButtonWindow
类型也被定义为Window
类型。这意味着它正在向Gtk.Window
class 添加更多详细信息。这就是title
和set_border_width()
可以在新的 class 中使用的原因。他们已经 "inherited" 从 parentGtk.Window
class - 通过使用带有
uses Gtk
的 Gtk 命名空间,我们不需要在所有内容前加上Gtk
随着您的 Gtk 应用程序变得越来越复杂,您可能想要查看 GtkBuilder
。这允许 windows 和小部件放置在外部文件中。然后使用 GResource
将文件构建到应用程序的二进制文件中,这样就无需单独分发 UI 文件。