在GTK中还是新手,现在正在努力处理事件驱动的编程并陷入奇怪的境地:将标量项发送到回调函数没有问题,但后来发送结构到它,仍然收到错误不知道出了什么问题。
示例“存根”代码是:
#include <gtk/gtk.h>
#include <stdlib.h>
void messageup();
void exiting();
struct data{
char *message;
GtkWidget *window;
};
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
GtkWidget *entryMainValue;
struct data d;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "samplemain.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "applicationwindow1"));
entryMainValue = GTK_WIDGET (gtk_builder_get_object (builder, "entryMainValue"));
g_signal_connect (window, "delete_event", G_CALLBACK (exiting), NULL);
d.message = "message\n";
d.window = window;
g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
g_object_unref (G_OBJECT (builder));
gtk_widget_show (window);
gtk_main ();
return 0;
}
void messageup(GtkWidget *entryMainValue, gpointer user_data){
struct data *d = (struct data*) user_data;
g_print("Hello World!\n%s\n", user_data.message);
}
void exiting()
{
exit(0);
}
现在出现如下错误:
gtkbldprj.c: In function ‘main’:
gtkbldprj.c:29:3: error: incompatible type for argument 4 of ‘g_signal_connect_data’
g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
^
In file included from /usr/include/glib-2.0/gobject/gobject.h:28:0,
from /usr/include/glib-2.0/gobject/gbinding.h:29,
from /usr/include/glib-2.0/glib-object.h:23,
from /usr/include/glib-2.0/gio/gioenums.h:28,
from /usr/include/glib-2.0/gio/giotypes.h:28,
from /usr/include/glib-2.0/gio/gio.h:26,
from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from gtkbldprj.c:1:
/usr/include/glib-2.0/gobject/gsignal.h:388:9: note: expected ‘gpointer’ but argument is of type ‘struct data’
gulong g_signal_connect_data (gpointer instance,
^
gtkbldprj.c: In function ‘messageup’:
gtkbldprj.c:42:41: error: request for member ‘message’ in something not a structure or union
g_print("Hello World!\n%s\n", user_data.message);
^
gtkbldprj.c:39:15: warning: unused variable ‘d’ [-Wunused-variable]
struct data *d = (struct data*) user_data;
任何帮助将不胜感激!
答案 0 :(得分:4)
这里有几个C错误。
GTK允许您在某些功能上传递gpointer user_data
。 gpointer
只是void *
(即指向某事的指针)。如果要传递结构,则需要结构的地址,而不是结构本身。这被称为传递地址,而不是传递值。
所以,而不是:
g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
写:
g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), &d);
然后,当您进行回调时,您收到的user_data
参数是指向某事的指针。您需要将其转换为指向结构的指针。
所以而不是:
void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
struct data *d = (struct data*) user_data;
g_print("Hello World!\n%s\n", user_data.message);
}
您需要使用正确类型的指针(d
,而不是user_data
)访问消息字段,并使用->
运算符作为您'通过指针访问结构:
void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
struct data *d = user_data;
g_print("Hello World!\n%s\n", d->message);
}
你似乎对指针感到困惑,所以看看这个好video about C pointers。
另一个错误是连接到delete-event
退出。此事件是您希望捕获用户单击窗口的退出十字或使用Alt-F4退出的事实,并且您希望在此时执行某些操作(显示确认弹出窗口,保存一些数据)。所以没有必要在那里连接,将发生破坏(使用destroy
信号)。
所以改为连接到delete-event
信号,连接到destroy
信号,并响应此信号,退出GTK +主循环:
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);