问题
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