G_object_bind_property () gives unexpected result

I am not sure how this Function works and I notice it after I tried to use it, that something is not OK.

Lets pretend that we have a Window with a grid inside which has two buttons.

on fist button the sensitive is default, on the second button I set its sensitive to FALSE.

After that I am calling the function like this:

g_object_bind_property( open_Button, "sensitive", close_button, "sensitive", 0 );

latter I set the property of the fist button to TRUE ( even if it has this property set already during its creation) there is no changes to second button.

To have the desired result I need fist to set the first button to FALSE and then back to TRUE so that the value of the second button get changes.

In other words, without this call:

g_object_set( open_Button, "sensitive", FALSE, NULL );

I get no changes on Second button.

How does exactly works this function, or how do I need to use it right?

Here is a demo code:

#include <gtk/gtk.h>

int main ( void )
{
    GtkWidget *window;
    GtkWidget *grid;

    GtkWidget *open_Button;
    GtkWidget *close_button;

    /// ***
    gtk_init ( NULL, NULL );

    /// *** Create a Window
    window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_default_size ( GTK_WINDOW ( window ), 200, 100 );

    /// ***
    grid   = gtk_grid_new ();

    gtk_container_add ( GTK_CONTAINER ( window ), grid );

    open_Button  = gtk_button_new_with_label( "Open"  );
    close_button = gtk_button_new_with_label( "Close" );

    /// ***
    g_object_set( open_Button, "margin", 25, NULL );

    /// ***
    g_object_set( close_button,
                "margin",       25,
                "sensitive",    FALSE,
                NULL );

    /// ***
    gtk_grid_attach( GTK_GRID( grid ), open_Button,  0, 0, 1, 1 );
    gtk_grid_attach( GTK_GRID( grid ), close_button, 1, 0, 1, 1 );

    g_object_bind_property( open_Button, "sensitive", close_button, "sensitive", 0 );

    /// *** I have to set the "sensitive" of open_button to FALSE fist
    ///g_object_set( open_Button, "sensitive", FALSE, NULL );

    /// If I set explicit to FALSE then this call updates the close_button
    g_object_set( open_Button, "sensitive", TRUE, NULL );



    gtk_widget_show_all( window );
    gtk_main ();
}

IMPORTANT!!!
This behavior does not happen if I do not set the second button (close_button) to FALSE.

#include <gtk/gtk.h>

int main ( void )
{
    GtkWidget *window;
    GtkWidget *grid;

    GtkWidget *open_Button;
    GtkWidget *close_button;

    /// ***
    gtk_init ( NULL, NULL );

    /// *** Create a Window
    window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_default_size ( GTK_WINDOW ( window ), 200, 100 );

    /// ***
    grid   = gtk_grid_new ();

    gtk_container_add ( GTK_CONTAINER ( window ), grid );

    open_Button  = gtk_button_new_with_label( "Open"  );
    close_button = gtk_button_new_with_label( "Close" );

    g_object_set( open_Button,  "margin", 25, NULL );
    g_object_set( close_button, "margin", 25, NULL );

    /// ***
    gtk_grid_attach( GTK_GRID( grid ), open_Button,  0, 0, 1, 1 );
    gtk_grid_attach( GTK_GRID( grid ), close_button, 1, 0, 1, 1 );

    g_object_bind_property( open_Button, "sensitive", close_button, "sensitive", 0 );
    g_object_set( open_Button, "sensitive", FALSE, NULL );

    gtk_widget_show_all( window );
    gtk_main ();
}

In a nutshell, it connect’s to the source object’s notify signal for the source property to set the target object’s target property.

The notify signal is meant to notify about property changes, so it’s not wrong for an object to not emit it when the property value did not actually change.

What you are likely looking for in this case is the G_BINDING_SYNC_CREATE flag:

g_object_bind_property( open_Button, "sensitive",
                        close_button, "sensitive", 
                        G_BINDING_SYNC_CREATE );

will set close_button’s sensitive property to the value of open_button’s sensitive property when creating the binding.

Of course for the exact working of the function, you can read it - one of the niceties of free software :slight_smile:

Yes this could work, but I have to stick with it and this is not what I need.
I need it to use it on G_BINDING_DEFAULT or with G_BINDING_BIDIRECTIONAL and not with
G_BINDING_SYNC_CREATE.

If you cannot use G_BINDING_SYNC_CREATE, then you must make sure that the initial property values are correct.

1 Like

Yes, I noticed.
Thank you for your time and help.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.