我正在构建一个执行以下操作的 GTK 程序:用户单击一个按钮,它从服务器检索信息,然后创建用户可以单击的新按钮。从技术上讲,我在 main 中有一个信号,在那个 call_back 中我有多个信号(对于每个创建的按钮)。
我想将数据传递给这个新按钮,但在这里它变得很恶心。如果我在我的第一个按钮中创建一个结构,我稍后会在生成的按钮中崩溃,因为该结构是在堆栈上本地定义的,因此它被删除了。
我无法创建全局变量,因为每个创建的按钮都需要不同的值。当我的初始按钮(回调方法)被调用时,我基本上想传递一个包含多个字段的结构,但每个结构都是不同的。
我能想到的唯一方法是在堆上分配它,但知道何时释放它会变得有点开销。
请问有解决此问题的好方法,还是我通过让信号处理程序创建新的信号处理程序来遵循错误的 GTK 设计选择?
非常感谢。
编辑:
我还在崩溃,我很困惑为什么。
这是主按钮的代码:
struct buttonData* data = (struct buttonData*) malloc(sizeof(struct buttonData));
data->IP = strdup(newDevice.IP.c_str()); // Added strdup
data->port = atoi(newDevice.port.c_str());
g_signal_connect(G_OBJECT(deviceButton), "button_press_event", G_CALLBACK(showDeviceAndConnect), (gpointer) data);
生成的按钮代码:
static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data) {
struct buttonData* toConnect = (struct buttonData *) data;
fprintf(stderr, "IP: %s, PORT: %d\n", toConnect->IP, toConnect->port); //SIGSEGV
}
我不知道为什么。任何帮助将不胜感激。
最佳答案
崩溃的原因是您的回调签名。 "button-press-event"
期望带有签名的回调 gboolean foo(GtkWidget* , GdkEvent*, gpointer)
。由于您的回调具有 void foo (GtkWidget * , gpointer )
的签名,因此您在回调函数中获得的第二个参数不是注册回调时使用的 gpointer 数据,而是 GdkEvent 指针。因此,当您取消引用 GdkEvent 指针(将其视为您传递的数据)时,您会看到崩溃。因此,要解决此问题,请将 static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data)
更改为 static void showDeviceAndConnect(GtkWidget * deviceButton, GdkEvent *ev, gpointer data)
。
或者,由于您仅使用 showDeviceAndConnect
函数中的数据,您可以使用 g_signal_connect_swapped
它将数据作为第一个参数传递;因此,如果您使用 g_signal_connect_swapped
,您的函数 static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data)
可以是 static void showDeviceAndConnect(gpointer data)
。< br/>
希望这对您有所帮助!
关于c - GTK+ : issues passing data to call_back functions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8144770/