您对全局变量保持警惕是正确的,特别是如果您只想允许某些函数修改它们。
假设您保留的数据不仅仅是A
(为简单起见,我将其定义为int
),您可以以熟悉的方式设置您的结构
typedef struct t_MYCBSD
{
int A;
// other members
} MYCBSD; // callback struct data
必要时包括其他数据成员。(我已经包括了t_MYCBSD
,以防有一些自我引用)。
然后,您可以按如下方式实现回调函数:
void callback_func1( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
data->A = some_func();
}
void callback_func2( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
data->A = another_func();
}
void callback_func3( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
if( data->A > threshold ) do_something();
else do_nothing();
}
显然,、 、some_func()
和another_func()
在这种情况下是有效的。threshold
do_something()
do_nothing()
注意:指向结构的data
指针使语法更加清晰。您还可以使用:
((MYCBSD *) user_data)->A = some_func();
无论如何,您通常在创建小部件时设置回调。在以下(大量剔除,非 GtkBuilder)代码中,MYCBSD mydata
将在本地范围内。我假设将为某些带有“单击”事件的按钮设置回调。
int main( int argc, char* argv[] )
{
MYCBSD mydata;
// Below-referenced widgets
GtkWidget *mywidget1, *mywidget2, *mywidget3;
// ... other widgets and variables
mydata.A = 0; // Optionally set an initial value to A
// Standard init via gtk_init( &argc, &argv );
// ... Create the toplevel and a container of some kind
// Create mywidget1,2,3 (as buttons, for example)
mywidget1 = gtk_button_new_with_label ("widget1");
mywidget2 = gtk_button_new_with_label ("widget2");
mywidget1 = gtk_button_new_with_label ("widget3");
g_signal_connect( mywidget1, "clicked", G_CALLBACK(callback_func1), &mydata );
g_signal_connect( mywidget2, "clicked", G_CALLBACK(callback_func2), &mydata );
g_signal_connect( mywidget3, "clicked", G_CALLBACK(callback_func3), &mydata );
// ... Attach those widgets to container
// ... and show all
// Run the app in a standard way via gtk_main();
return 0;
}
这里的重要行是:
g_signal_connect( mywidget1, "clicked", G_CALLBACK(callback_func1), &mydata );
g_signal_connect( mywidget2, "clicked", G_CALLBACK(callback_func2), &mydata );
g_signal_connect( mywidget3, "clicked", G_CALLBACK(callback_func3), &mydata );
最后一个参数将您的数据传递给回调函数。
如果您只想共享一个值,A
则可以以类似的方式传递它,而无需结构。