2010-08-10 142 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()爲您提供的類型檢查。

相關問題