Gtk 如何有条件地绑定两个属性?

Gtk 如何有条件地绑定两个属性?,gtk,glib,vala,genie,Gtk,Glib,Vala,Genie,我已经有一段时间没有成功地解决这个问题了。这是一个练习,旋转按钮和刻度不断同步,同时勾选检查按钮。但是,当复选按钮未激活时,缩放和旋转都可以自由获取任何值 在前面的一个问题中,建议使用bind_属性方法,当您希望旋转和缩放始终同步时,这种方法非常有效。但是,当需要将其链接到check按钮的活动(或缺少活动)时,它不起作用。第二次单击check按钮时,程序挂起 以下是我所取得的成绩: [indent=4] uses Gtk class TestWindow:Window _sp

我已经有一段时间没有成功地解决这个问题了。这是一个练习,旋转按钮和刻度不断同步,同时勾选检查按钮。但是,当复选按钮未激活时,缩放和旋转都可以自由获取任何值

在前面的一个问题中,建议使用bind_属性方法,当您希望旋转和缩放始终同步时,这种方法非常有效。但是,当需要将其链接到check按钮的活动(或缺少活动)时,它不起作用。第二次单击check按钮时,程序挂起

以下是我所取得的成绩:

[indent=4]
uses
    Gtk

class TestWindow:Window

    _spin:SpinButton
    _scale:Scale
    _check:CheckButton

    construct ()
        //General aspects of the window
        title = "Spin and scale"
        window_position = WindowPosition.CENTER
        destroy.connect( main_quit )

        //create the spin button
        spinAdjustment:Adjustment = new Adjustment( 50, 0, 100, 1, 5, 0 )
        scaleAdjustment:Adjustment = new Adjustment( 50, 0, 100, 1, 5, 0 )
        _spin = new SpinButton( spinAdjustment, 1.0, 1 )

        //create the horizontal scale
        _scale = new Scale( Orientation.HORIZONTAL, scaleAdjustment );

        //create the check button
        _check =  new CheckButton.with_label ( "Sync both scales!" )
        _check.set_active(true)
        _check.toggled.connect( toggled )

        // organize it in a box
        var box = new Box( Orientation.VERTICAL, 0 )
        box.pack_start( _spin, true, true, 0 )
        box.pack_start( _scale, true, true, 0 )
        box.pack_start( _check, true, true, 0 )
        add( box )


    def toggled ()
        if (_check.active)
            _spin.adjustment.bind_property( "value", _scale.adjustment, "value",BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL )

init
    Gtk.init( ref args )
    var test = new TestWindow()
    test.show_all()
    Gtk.main()
有人建议如何将绑定链接到checkbutton,使其只在按下时同步吗?我是否应该继续寻找其他解决问题的策略


感谢要撤消绑定,您必须调用
bind\u属性返回的
bind
绑定的
unbind
方法:

    _binding:Binding

    construct ()
        // ...
        _check.toggled.connect( toggled )
        _check.set_active(true)
        // ...

def toggled ()
    // If there was a binding object before
    if (_binding != null)
        // .. unbind it
        _binding.unbind ()
        // and set it to null to indicate "not bound" state
        _binding = null
    // Bind if necessary
    if (_check.active)
        _binding = _spin.adjustment.bind_property( "value", _scale.adjustment, "value",BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL )
要手动执行此操作,您可以使用
值\u changed
事件:

    construct ()
        // ...
        _spin.value_changed.connect (spin_value_changed)
        _scale.value_changed.connect (scale_value_changed)
        _check.toggled.connect (check_toggled)
        _check.set_active(true)
        // ...

    def spin_value_changed ()
        // Only sync, when checkbox is set
        if (_check.active)
            // Avoid circle, only set if different
            if (_scale.get_value () != _spin.get_value ())
                _scale.set_value (_spin.get_value())

    def scale_value_changed ()
        // Only sync, when checkbox is set
        if (_check.active)
            // Avoid circle, only set if different
            if (_scale.get_value () != _spin.get_value ())
                _spin.set_value (_scale.get_value())

    def check_toggled ()
        spin_value_changed ()

我更改了你的问题标题,因为这个后续问题不是关于原始问题,而是关于bind_属性行为。调用
bind_属性
返回一个对象,该对象具有一个
unbind
方法。所以我不认为解绑是个问题。更难的是以一种优雅的方式维护一个状态记录,即它是被绑定的还是未绑定的。我认为在代码中避免
null
s是一种很好的做法,而添加一个额外的布尔值来保持状态是不雅观的。理想情况下,构造函数将创建绑定对象,然后调用
unbind
rebind
。只有
rebind
不存在。只要处理得当,使用
null
就可以了,我还添加了一个使用unbind的示例。