我想使用g_signal_connect()
函数来更改特定struct/class
中的数据。因此,我认为最好的方法是使用指向struct
的指针。问题是指针的信息似乎一直在变化。
我花了很多时间弄清楚为什么会这样,但是我不知道。 我可以编译并运行代码而没有任何错误,但是输出总是不同的。
稍后,我想使用多个event_box连接到struct数组或类数组({event_box[0]
连接到data[0]
,...)。
我希望有人能理解我的意思,我会很乐意提供帮助。
#include<gtk/gtk.h>
struct d
{
bool status;
int ID;
};
void end_program(GtkWidget *wid, gpointer ptr)
{
gtk_main_quit();
}
void box_click(GtkWidget *wid, gpointer user_data)
{
struct d *data = (struct d*)user_data;
printf("status = %i\n", data->status);
printf("ID = %i\n", data->ID);
}
int main (int argc, char *argv[])
{
struct d data;
data.status = 0;
data.ID = 1;
gtk_init(&argc, &argv);
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkWidget *event_box = gtk_event_box_new();
g_signal_connect(G_OBJECT(event_box), "button_press_event", G_CALLBACK(box_click), &data);
gtk_container_add(GTK_CONTAINER(win), event_box);
gtk_widget_show_all(win);
g_signal_connect(win, "delete_event", G_CALLBACK(end_program),NULL);
gtk_main();
return 0;
}
如果我多次单击该框,则输出:
status = 4
ID = 32193184
status = 5
ID = 32193184
status = 4
ID = 32193184
status = 6
ID = 32193184
status = 4
ID = 32193184
答案 0 :(得分:1)
我希望有人能理解我的意思,我会为任何事情感到高兴 帮助。
嗯,是的。您正在为button-press-event
使用错误的函数原型。 button-press-event
的原型为:
The “button-press-event” signal
gboolean
user_function (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
(注意:信号正确"button-press-event"
,而不是"button_press_event"
,尽管有#define
允许第二种形式起作用)
请参见GtkWidget (Gtk+3 Manual)。所以您的函数应该是这样的:
gboolean box_click(GtkWidget *wid, GdkEvent *event, gpointer user_data)
{
struct d *data = user_data; /* no need for cast, gpointer is void* */
g_print("status = %d\n", data->status);
g_print("ID = %d\n", data->ID);
return TRUE; /* to prevent further handling, FALSE otherwise */
(void)wid; /* cast to void to avoid unused var warning */
(void)event;
}
其他功能
使用g_print
代替printf
,使用gboolean
代替bool
。通过address of
对于小型结构很好,对于大型结构,应分配g_slice_new
。
答案 1 :(得分:0)
我将在@David C. Rankin说过的那部分进行扩展:
IsHidden= true;
onSelect(){
this.IsHidden=true;
this.IsHidden= !this.IsHidden;
}
因为有些重要的东西很多人都不知道。
大多数时候,错误地使用了强制转换,这是因为还有另一个函数被称为:
(void)wid; /* cast to void to avoid unused var warning */
(void)event;
在那里可以通过将fist参数与最后一个参数交换来避免大量的转换。
让我们举一个例子:
g_signal_connect_swapped()
在这里您可以看到回调函数签名如下:
#include <gtk/gtk.h>
GtkWidget *createWindow ( const gint width, const gint height );
void user_function ( GtkWidget *object, gpointer user_data );
int main ( void )
{
GtkWidget *window;
gtk_init ( NULL, NULL );
/// ***
window = createWindow( 300, 300 );
/// ***
g_signal_connect ( window, "destroy", G_CALLBACK( user_function ), NULL );
/// ***
gtk_widget_show_all ( window );
gtk_main();
}
GtkWidget *createWindow ( const gint width, const gint height )
{
GtkWidget *window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_widget_set_size_request ( window, width, height );
gtk_container_set_border_width ( GTK_CONTAINER ( window ), 50 );
return window;
}
void user_function ( GtkWidget *object, gpointer user_data )
{
(void)object;
(void)user_data;
g_print( "Goodbye\n" );
gtk_main_quit();
}
现在在这种情况下需要两个强制类型转换,但是我们可以像这样通过调用void user_function ( GtkWidget *object, gpointer user_data )
来丢弃其中一个(例如指针数据):
g_signal_connect_swapped
甚至更好:
g_signal_connect_swapped ( window, "destroy", G_CALLBACK( user_function ), NULL
现在我们的程序如下:
g_signal_connect_swapped ( window, "destroy", G_CALLBACK( user_function ), (gpointer)"Goodbye" );
并且不再有CAST。
这是一个更好的例子:
#include <gtk/gtk.h>
GtkWidget *createWindow ( const gint width, const gint height );
void user_function ( gpointer data );
int main ( void )
{
GtkWidget *window;
gtk_init ( NULL, NULL );
/// ***
window = createWindow( 300, 300 );
/// ***
g_signal_connect_swapped ( window, "destroy", G_CALLBACK( user_function ), (gpointer)"Goodbye" );
/// ***
gtk_widget_show_all ( window );
gtk_main();
}
GtkWidget *createWindow ( const gint width, const gint height )
{
GtkWidget *window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_widget_set_size_request ( window, width, height );
gtk_container_set_border_width ( GTK_CONTAINER ( window ), 50 );
return window;
}
void user_function ( gpointer data )
{
g_print( "%s\n", (char*)data );
gtk_main_quit();
}