2010-08-10 134 views
2

我正在用C写一个GTK +应用程序(虽然这里的原理是广泛适用的),它包含一个GtkComboBox。 GtkComboBox是由另一个函数返回的更大结构的一部分,并打包到主窗口中。在这种情况下可以避免使用全局变量吗?

我不明白我怎么能得到GtkComboBox中选择的值,而不是通过从其回调函数中设置全局变量。或者在程序的后面还有一些方法可以引用GtkComboBox,而不是在声明它的函数之外?

或者我不应该首先在函数内部(main()以外)声明它吗?

回答

1

如果在C语言中声明堆栈变量的函数已经返回,那么该变量就没有了。如果您需要GtkComboBox(或其他物体)坚持,你有几种选择:

  • 使用malloc为它分配空间,并通过围绕一个指针(当你不再需要它必须被释放)。
  • 使用全局变量
  • 不要使用回调并在外部函数中声明并传递它。

我可能会用malloc/pass围绕一个指针方法,但不能确定没有更多的知识你的情况。

+0

我认为这基本上是,但malloc()类混淆了我。 GtkComboBox只作为一个指针被声明(即GtkWidget * combo_box,后来在combo_box = gtk_combo_box_new(...))我应该在这里使用malloc()以便稍后再看,或者GTK +可以为我处理所有这些? – tsvallender 2010-08-10 20:08:24

+0

啊,这是我不知道从GTK进来的地方。如果组合框已经作为指针传递了,你只需要让你的指针是全局的,或者将指针传递给你的函数。不需要'malloc'指针指针。如果你不能传递指针(由于函数参数的限制),你必须去全局路由。 – nmichaels 2010-08-10 20:15:19

+0

这听起来很合适,非常感谢。 – tsvallender 2010-08-10 20:30:51

0

我不确定我清楚地明白你想达到的目标。但是,创建持久变量的一种方法是使用静态变量,而不使用全局变量。例如根据我对你的希望,你可以做什么可能误解了以下内容:

GtkComboBox *getComboBox() 
{ 
    static GtkComboBox gcb = NULL; 

    if (NULL != gcb) 
    return gcb; 

    // Initialise gcb 
    return gcb; 
} 
4

我看你已经接受了答案,但因为GTK有处理这一切优雅的机制,我觉得有必要反正写另一个。

gtk_combo_box_new()在内部使用malloc()来分配它返回的指针。 (嗯,严格来说,事实并非如此,但我们不要在此混淆)。因此,您的GtkComboBox将保持活动状态,直到它的父控件被销毁,或者从其父控件中删除,或者直到您手动销毁它(使用gtk_widget_destroy(),不是free())。所以,这个小部件仍然存在于后台,但问题是在你需要的地方有一个指向它的指针。

由于GTK程序中的大部分工作都是在信号处理程序中完成的,通常您会想要操作组合框以响应信号。如果是组合框本身的信号之一,像changed信号,那么回调会是这样一个功能:

void on_combo_box_changed(GtkComboBox *combo_box, gpointer user_data) 

combo_box将是指向您的组合框。

如果你要处理的组合框响应到其他窗口的信号,比方说,一个按钮的clicked信号,那么回调会是这样一个功能:

void on_button_clicked(GtkButton *button, gpointer user_data) 

正如你所看到的,有这里没有指向组合框的指针。这里是参数user_data的地方。我假设你在你构建小部件的函数中连接你的信号并将它们打包到你的主窗口中。 (如果你不是,你应该是)。在这个函数中,你将有指向按钮和组合框的指针。连接你的信号是这样的...

g_signal_connect(button, "clicked", G_CALLBACK(on_button_clicked), combo_box); 

...传递combo_box作为user_data参数g_signal_connect()。然后指向组合框的指针将被传递给on_button_clicked()回调,伪装成user_data参数。然后,您可以访问它像这样:

void on_button_clicked(GtkButton *button, gpointer user_data) 
{ 
    GtkComboBox *combo_box = GTK_COMBO_BOX(user_data); 
    gint item = gtk_combo_box_get_active(combo_box); 
    etc. 

,或者由于调用堆栈在C工作,甚至通过声明回调像这样的方式:

void on_button_clicked(GtkButton *button, GtkComboBox *combo_box) 

......虽然那么你输GTK_COMBO_BOX()为您提供的类型检查。

相关问题