首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >signal.connect语法

signal.connect语法
EN

Stack Overflow用户
提问于 2016-01-09 04:44:28
回答 1查看 118关注 0票数 1

我正在尝试用两个FileChooserButtons创建一个窗口。第一个应该帮助用户选择一个目录,因此我使用操作Select_folder;第二个是允许用户选择一个文件。

问题是,我希望第二个文件夹根据用户在第一个文件夹中的选择更改当前文件夹。

我最初的想法是使用Signal.connect,如行中所示:

代码语言:javascript
复制
Signal.connect(chooser1, "selection_changed", folder_changed, null)

但是,这会导致以下编译错误:

代码语言:javascript
复制
exercise4_1.gs:62.55-62.68: error: Cannot create delegate without target for instance method or closure
        Signal.connect(chooser1, "selection_changed", folder_changed, null)
                                                      ^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)

我还试着在vala邮件列表中按照这个folder_changed添加(回调) 邮件通信,但没有效果。

以下是整个代码:

代码语言:javascript
复制
[indent=4]

uses
    Gtk
    GLib

class TestWindow : Window
    chooser1:Gtk.FileChooserButton
    chooser2:Gtk.FileChooserButton
    construct()

        // General characteristics of the window
        title = "File chooser"
        window_position = WindowPosition.CENTER
        destroy.connect(Gtk.main_quit)
        chooser1 = new FileChooserButton(
                                            "Choose a Folder",
                                            FileChooserAction.SELECT_FOLDER
                                            )
        chooser2 = new FileChooserButton(
                                             "Chooser a Folder",
                                             FileChooserAction.OPEN
                                             )
        chooser1.set_current_folder(Environment.get_home_dir())
        chooser2.set_current_folder(Environment.get_home_dir())

        Signal.connect(chooser1, "selection_changed", folder_changed, null)

        var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0)
        box.pack_start(chooser1, true, true,0)
        box.pack_start(chooser2, true, true,0)
        add(box)


    def folder_changed()
        var folder = chooser1.get_filename()
        chooser2.set_current_folder(folder)


init
    Gtk.init (ref args)
    var test = new TestWindow ()
    test.show_all ()
    Gtk.main ()
  1. 这当然是我对这个特定语法缺乏理解,但由于我被困住了,我希望能有一个指针来帮助我摆脱它。
  2. 作为额外的、不太重要的一点,最佳实践是什么:分割和缩进长行,或者允许它们出现在代码中?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-09 18:37:18

Gtk的回调需要包含生成信号的对象的参数。此外,Genie和Vala对GLib信号有语法支持,以使信号更易于使用。下面是一个基于代码的示例:

代码语言:javascript
复制
[indent=4]
uses
    Gtk

class TestWindow:Window
    _file_chooser:FileChooserButton

    construct()
        title = "File chooser"
        window_position = WindowPosition.CENTER
        destroy.connect( Gtk.main_quit )

        var folder_chooser = new FileChooserButton(
                                         "Choose a Folder",
                                         FileChooserAction.SELECT_FOLDER
                                        )
        folder_chooser.set_current_folder( Environment.get_home_dir() )
        folder_chooser.selection_changed.connect( folder_changed )

        _file_chooser = new FileChooserButton(
                                        "Chooser a File",
                                        FileChooserAction.OPEN
                                        )
        _file_chooser.set_current_folder( Environment.get_home_dir() )

        var box = new Box( Orientation.VERTICAL, 0 )
        box.pack_start( folder_chooser, true, true, 0 )
        box.pack_start( _file_chooser, true, true, 0 )
        add( box )

    def folder_changed( folder_chooser_widget:FileChooser )
        folder:string = folder_chooser_widget.get_uri()
        _file_chooser.set_current_folder_uri( folder )

init
    Gtk.init( ref args )
    var test = new TestWindow()
    test.show_all()
    Gtk.main()

有几点需要注意:

  • 信号名,"selection_changed"已经成为folder_chooser的一个属性,然后是connect。Vala编译器在编译时完成对GLib.Signal的转换。
  • FileChooserButtonfolder_chooser,已从类的作用域中删除。现在通过将它作为参数传递给回调来访问它。因此,它被定义为回调函数的参数。
  • 您将注意到回调的参数需要FileChooser类型,而不是FileChooserButton类型。这是因为selection_changed信号是FileChooserButton随后实现的FileChooser接口的一部分。这实际上为FileChooserButton提供了多个类型
  • 尽管_file_chooser被声明为在类的整个范围内都可用,但只有在类中使用下划线才能访问它。

使用Signal.connect()更接近于Gtk的closer。如果您需要这样做,那么以下工作将基于您的原始代码:

代码语言:javascript
复制
[indent=4]
uses
    Gtk

class TestWindow:Window
    chooser1:FileChooserButton
    chooser2:FileChooserButton
    construct()

        // General characteristics of the window
        title = "File chooser"
        window_position = WindowPosition.CENTER
        destroy.connect( Gtk.main_quit )
        chooser1 = new FileChooserButton(
                                         "Choose a Folder",
                                         FileChooserAction.SELECT_FOLDER
                                        )
        chooser2 = new FileChooserButton(
                                        "Chooser a Folder",
                                        FileChooserAction.OPEN
                                        )
        chooser1.set_current_folder( Environment.get_home_dir() )
        chooser2.set_current_folder( Environment.get_home_dir() )

        Signal.connect( 
                      chooser1, 
                      "selection_changed", 
                      (GLib.Callback)folder_changed,
                      self
                      )

        var box = new Box( Orientation.VERTICAL, 0 )
        box.pack_start( chooser1, true, true, 0 )
        box.pack_start( chooser2, true, true, 0 )
        add( box )

    [CCode( instance_pos = 2 )]
    // or [CCode( instance_pos = -1 )] to always be last
    def folder_changed( folder_chooser:Widget )
        folder:string = chooser1.get_uri()
        chooser2.set_current_folder_uri( folder )

init
    Gtk.init( ref args )
    var test = new TestWindow()
    test.show_all()
    Gtk.main()

有几点需要注意:

  • 是的,您确实需要将回调转换为GLib.Callback,就像您在链接到的邮件中发现的那样
  • 您需要的实例数据是您为其创建的Window对象,因此将null更改为self在这里有效。
  • Vala会将实例数据作为第一个参数,因此要覆盖默认情况,必须使用CCode属性,在本例中为[CCode( instance_pos = 2 )]
  • 生成信号的对象仍然是回调函数的第一个参数,因此即使在本例中它未使用,它仍然存在于定义中。这被定义为Widget类型,但可以将其更改为FileChooser以使用get_uri()调用

对于代码格式问题,如您所见,我更喜欢分割长行。到目前为止,我还不确定对精灵是否有一致的“最佳实践”。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34689763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档