member function as callback function to g_signal_connect

二次信任 提交于 2020-02-28 06:28:44

问题


I have created a simple class for creating gtk main window.

I want to know what is correct way to pass class member function as an argument to G_CALLBACK function?

Why

g_signal_connect(button, "clicked", G_CALLBACK(&MainWindow: nButtonClicked), NULL);

is bad?

#include <gtk/gtk.h>

class MainWindow {
public:
    MainWindow();
    ~MainWindow();
    void onButtonClicked(GtkWidget* button, gpointer* data);
    void showWindow();

private:
    GtkWidget* window;
    GtkWidget* button;
};
MainWindow::MainWindow()
{
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);

    button = gtk_button_new_with_label("click here");
    g_signal_connect(button, "clicked", G_CALLBACK(&MainWindow: nButtonClicked), NULL);

    gtk_container_add(GTK_CONTAINER(window), button);
}

MainWindow::~MainWindow()
{
}

void MainWindow::onButtonClicked(GtkWidget* button, gpointer* data)
{
    g_printerr("button clicked\n");
}

void MainWindow::ShowWindow() {
    gtk_widget_show_all(window);
}

int main(int argc, char* argv[]) {
    gtk_init(&argc, &argv);

    MainWindow mainWindow;
    mainWindow.showWindow();

    gtk_main();
    return 0;
}

回答1:


You have to pass a static function and the this-pointer:

class Window 
{
    public:
    virtual void on_button_clicked(GtkWidget* button);

    void connect_button_clicked(GtkWidget* button) {
        g_signal_connect(
            button, 
            "clicked", 
            G_CALLBACK(button_clicked_callback), this);
    }

    private:
    static void button_clicked_callback(GtkWidget* button, gpointer* data) {
        reinterpret_cast<Window*>(data)->on_button_clicked(button);
    }
};

Passing a pointer to a member function will not work (incompatible types and no reference to an object). If the c-callback mechanism does not support custom data (the this pointer here) things will get ugly.




回答2:


Although static methods happen to work with some compilers (most notably gcc), someone told me this is not always the case.

The proper way is to declare the callback (or at least a wrapper function) outside the class. Better yet, use proper C++ bindings for GTK+. Better yet, use C.



来源:https://stackoverflow.com/questions/21478803/member-function-as-callback-function-to-g-signal-connect

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!