Search code examples
dgtkd

gtkd addOnClicked/g_signal_connect fails


I am looking to set up a button that loads function "NewItem" when the button is pressed. When I attempt to compile, I get the message:

./test.d:20: Error: function gtk.Button.Button.addOnClicked (void delegate(Button) dlg, 
GConnectFlags connectFlags = cast(GConnectFlags)0) is not callable using argument types 
(void function())
./test.d:20: Error: cannot implicitly convert expression (& NewItem) of type void 
function() to void delegate(Button)

Under C (I am doing a rewrite of a C program in D), I would just use g_signal_connect(NewItem_button, "clicked", G_CALLBACK(NewItem), NULL);, but I believe I would use NewItem_button.addOnClicked(&NewItem); in D.

My code is:

void NewItem()
{
    //Create a new window to add new items.
}

Grid config_menu()
{
    Button tax_button=new Button("Set Tax Rate");

    Button NewItem_button=new Button("New Menu Item");
    NewItem_button.addOnClicked(&NewItem);

    Grid admin_grid=new Grid();
    admin_grid.setColumnSpacing(6);
    admin_grid.setRowSpacing(3);

    admin_grid.attach(tax_button, 0,0,1,1);
    admin_grid.attach(NewItem_button, 1,0,1,1);

    return(admin_grid);
}

Solution

  • addOnClicked requires a parameter of type void delegate(Button) dlg while you are providing it a parameter of type void function().

    The difference between a delegate and a function is that a delegate has context too. You can read more about functions and delegates here: http://ddili.org/ders/d.en/lambda.html

    You're also missing that your function needs to take a parameter of type Button.

    To make your example work, you'll need to convert your function to a delegate, you'll need:

    void NewItem(Button b) // your function needs to take a Button parameter
    {
        //Create a new window to add new items.
    }
    
    Grid config_menu()
    {
        Button tax_button=new Button("Set Tax Rate");
    
        Button NewItem_button=new Button("New Menu Item");
        NewItem_button.addOnClicked(toDelegate(&NewItem)); // convert the function to a delegate
    
        Grid admin_grid=new Grid();
        admin_grid.setColumnSpacing(6);
        admin_grid.setRowSpacing(3);
    
        admin_grid.attach(tax_button, 0,0,1,1);
        admin_grid.attach(NewItem_button, 1,0,1,1);
    
        return(admin_grid);
    }
    

    Documentation for toDelegate: http://dlang.org/phobos/std_functional.html#.toDelegate