Как связать пользовательскую функцию с нажатием кнопки GTK?

Я работаю над учебным пособием Vala GTK+3, предоставленным Elementary OS. Я так понимаю этот код:

var button_hello = new Gtk.Button.with_label ("Click me!");
button_hello.clicked.connect (() => {
    button_hello.label = "Hello World!";
    button_hello.set_sensitive (false);
});

использует функцию Lambda для изменения метки кнопки при нажатии. Вместо этого я хочу вызвать эту функцию:

void clicked_button(Gtk.Button sender) {
    sender.label = "Clicked. Yippee!";
    sender.set_sensitive(false);
}

Я пробовал это:

button.clicked.connect(clicked_button(button));

Но я получаю эту ошибку от компиляции Vala, когда пытаюсь скомпилировать:

hello-packaging.vala:16.25-16.46: error: invocation of void method not allowed as expression
    button.clicked.connect(clicked_button(button));
                           ^^^^^^^^^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)

Я новичок как в Vala, так и в Linux, поэтому, пожалуйста, будьте нежны, но может ли кто-нибудь указать мне правильное направление?


person Garry Pettet    schedule 03.04.2017    source источник


Ответы (2)


Вам нужно передать ссылку на функцию, а не результат функции. Так должно быть:

button.clicked.connect (clicked_button);

Когда кнопка нажата, GTK+ вызовет функцию clicked_button с кнопкой в ​​качестве аргумента.

Сообщение об ошибке invocation of void method not allowed as expression говорит вам, что вы вызываете (вызываете) метод, и он не имеет результата (недействителен). Добавление круглых скобок () в конец имени функции вызывает эту функцию.

person AlThomas    schedule 03.04.2017
comment
Всегда ли экземпляр, излучающий сигнал, передается функции в качестве первого аргумента? Это то же самое для всех виджетов GTK? - person Garry Pettet; 03.04.2017
comment
Да, потому что обратный вызов должен иметь сигнатуру функции GtkCallback, которая в C является void (*GtkCallback) (GtkWidget *widget, данные gpointer); См. developer.gnome.org/gtk3/stable/GtkWidget.html#GtkCallback и valadoc.org/gtk+-3.0/Gtk.Callback.html . Часть пользовательских данных обычно скрыта в Vala, потому что это либо экземпляр класса, в котором определен метод, либо замыкание, в зависимости от того, был ли обратный вызов передан как имя функции или лямбда-выражение. - person AlThomas; 03.04.2017

Удалось заставить его работать. Вот код на случай, если он понадобится другим:

int main(string[] args) {
    //  Initialise GTK
    Gtk.init(ref args);

    // Configure our window
    var window = new Gtk.Window();
    window.set_default_size(350, 70);
    window.title = "Hello Packaging App";
    window.set_position(Gtk.WindowPosition.CENTER);
    window.set_border_width(12);
    window.destroy.connect(Gtk.main_quit);

    // Create our button
    var button = new Gtk.Button.with_label("Click Me!");
    button.clicked.connect(clicked_button);

    // Add the button to the window
    window.add(button);
    window.show_all();

    // Start the main application loop
    Gtk.main();
    return 0;
}

// Handled the clicking of the button
void clicked_button(Gtk.Button sender) {
    sender.label = "Clicked. Yippee!";
    sender.set_sensitive(false);
}
person Garry Pettet    schedule 03.04.2017