我是GTK +编程的新手,我在一周之后开始研究它,我主要只遇到一个大问题,这里是代码解释:
for(j=1;j<5;j++)
{
for(i=1;i<6;i++)
{
box[i][j] = gtk_hbox_new(TRUE, 0);
check[i][j]=gtk_check_button_new();
event[i][j]= gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (event[i][j]),color[i][j]);
gtk_box_pack_start(box[i][j],check[i][j], TRUE, FALSE, 0);
gtk_box_pack_start(box[i][j],event[i][j], TRUE, FALSE, 0);
gtk_widget_set_events (event[i][j], GDK_BUTTON_PRESS_MASK);
gtk_table_attach_defaults(table,box[i][j],j-1, j, i, i+1);
}
}
我有一张桌子,并且对于每个(i,j)我有一个包含可点击图像和复选框的框,我想在点击事件时关闭检查[i] [j]检查/不检查[i] [j](可点击图片) 所以信号就像这样
g_signal_connect (GTK_OBJECT(event[i][j]), "button-press-event",G_CALLBACK(events),NULL);
并且回调函数就像这样
void events(void)
{
void* k;
k= gtk_toggle_button_get_active(check[i][j]);
if(k==FALSE)
{
gtk_toggle_button_set_active(check[i][j],TRUE);
}
else
{
gtk_toggle_button_set_active(check[i][j],FALSE);
}
}
我没有找到如何将i和j传递给回调,我在g_signal_connect中使用包含i和j的结构/选项卡更改了NULL(还添加了gpointer数据和回调中的所有必需内容) )但没有工作...... 我花了很多时间在互联网上搜索,但我没有找到我真正需要的东西。 到目前为止我找到的唯一解决方案是为每个i,j创建20个回调函数和20个g_signal_connect,但代码需要大约270行... 非常感谢您的帮助:D
要解释更多: 这是结构:
typedef struct {
int i;
int j;
} t_ig ;
t_ig a;
循环:
for(j=1;j<5;j++)
{
for(i=1;i<6;i++)
{
box[i][j] = gtk_hbox_new(TRUE, 0);
check[i][j]=gtk_check_button_new();
event[i][j]= gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (event[i][j]),color[i][j]);
tr=event[i][j];
gtk_box_pack_start(box[i][j],check[i][j], TRUE, FALSE, 0);
gtk_box_pack_start(box[i][j],event[i][j], TRUE, FALSE, 0);
gtk_widget_set_events (event[i][j], GDK_BUTTON_PRESS_MASK);
a.i=i;
a.j=j;
g_signal_connect (GTK_OBJECT(tr)), "button-press-event",G_CALLBACK(events),&a);
}
回调
void events(GtkWidget * tr, gpointer userdata)
{
t_ig * d = (t_ig *) userdata ;
printf ("%d",d->i);
}
我通常应该得到我用a.i = i初始化的i;因为我没有得到i和j的必要值,所以我无法编辑check [i] [j]
编辑: 我的问题解决了,对于那些可能感兴趣的人是代码:
for(j=1;j<5;j++)
{
for(i=1;i<6;i++)
{
box[i][j] = gtk_hbox_new(TRUE, 0);
check[i][j]=gtk_check_button_new();
event[i][j]= gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (event[i][j]),color[i][j]);
tr=event[i][j];
gtk_box_pack_start(box[i][j],check[i][j], TRUE, FALSE, 0);
gtk_box_pack_start(box[i][j],event[i][j], TRUE, FALSE, 0);
gtk_widget_set_events (event[i][j], GDK_BUTTON_PRESS_MASK);
g_signal_connect ((GTK_OBJECT(event[i][j])), "button-press-event",G_CALLBACK(events),check[i][j]);
}
}
回调:
void events(GtkWidget * wid,GdkEvent *event, gpointer userdata)
{
GtkWidget * d=userdata;
void* k;
k= gtk_toggle_button_get_active(d);
if(k==FALSE)
{
gtk_toggle_button_set_active(d,TRUE);
}
else
{
gtk_toggle_button_set_active(d,FALSE);
}
(void) wid;
}
谢谢大家的回答:D
答案 0 :(得分:0)
button-press-event的定义如下:
gboolean
user_function (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
您的回调必须有此签名。
第二个问题是您正在重用相同的数据结构。这不会起作用:你需要为每个不同的分配一个结构:例如ti_g *data = g_slice_new0 (ti_g);
但是......如果您只想修改回调中的特定复选框,为什么不直接将指向该复选框的指针作为用户数据指针,如下所示:
gboolean
button_press_event_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
GtkToggleButton *btn = GTK_TOGGLE_BUTTON (user_data);
gboolean active = gtk_toggle_button_get_active (btn);
gtk_toggle_button_set_active (btn, !active);
return TRUE;
}
/* ... in construction code ... */
g_signal_connect (event[i][j], "button-press-event",
G_CALLBACK(button_press_event_cb), check[i][j]);