2010-07-12 107 views
1

我收到了嘗試編譯以下代碼的分段錯誤。我的問題是,這是從GtkEntry獲取文本的正確方法嗎?如果是這樣,爲什麼我得到分段錯誤?如果不是,從GtkEntry中檢索文本的正確方法是什麼?從GtkEntry獲取文本

void dialogoIngresarDados(GtkWidget *window){ 
GtkWidget *dialog; 
GtkWidget *vbox, *button; 
GtkWidget *hBoxDado1, *hBoxDado2, *label1, *label2; 
struct textEntries dados; 

dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
gtk_container_set_border_width(GTK_CONTAINER(dialog),5); 
gtk_widget_set_size_request(dialog ,200, 100); 
gtk_window_set_title(GTK_WINDOW(dialog), "Dados"); 
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); 

vbox = gtk_vbox_new(FALSE, 0); 

label1 = gtk_label_new("Dado1"); 
label2 = gtk_label_new("Dado2"); 
button = gtk_button_new_from_stock(GTK_STOCK_APPLY); 

dados.entryDado1 = gtk_entry_new_with_max_length(10); 
dados.entryDado2 = gtk_entry_new_with_max_length(10); 

hBoxDado1 = gtk_hbox_new(TRUE,0); 
hBoxDado2 = gtk_hbox_new(TRUE,0); 

gtk_box_pack_start_defaults (GTK_BOX (vbox), hBoxDado1); 
gtk_box_pack_start_defaults (GTK_BOX (vbox), hBoxDado2); 
gtk_box_pack_start_defaults (GTK_BOX (vbox), button); 

gtk_box_pack_start_defaults (GTK_BOX (hBoxDado1), label1); 
gtk_box_pack_start_defaults (GTK_BOX (hBoxDado1), dados.entryDado1); 

gtk_box_pack_start_defaults (GTK_BOX (hBoxDado2), label2); 
gtk_box_pack_start_defaults (GTK_BOX (hBoxDado2), dados.entryDado2); 

gtk_container_add (GTK_CONTAINER(dialog), vbox); 

g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(applyIngresarDados), &dados); 
g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(gtk_main_quit), NULL); 

gtk_widget_show_all (dialog); 
} 

點擊信號回調。

void applyIngresarDados(GtkButton *button, struct textEntries *dados){ 
const gchar *dado1; 
const gchar *dado2; 

dado1 = gtk_entry_get_text(GTK_ENTRY(dados->entryDado1)); 
dado2 = gtk_entry_get_text(GTK_ENTRY(dados->entryDado2)); 
} 

包含文本條目的結構。

struct textEntries{ 
GtkWidget *entryDado1; 
GtkWidget *entryDado2; 
}; 
+0

您是否在調試器中運行了代碼?究竟是什麼原因導致段錯誤? – zdav 2010-07-12 01:14:52

+0

gtk_entry_get_text()函數導致段錯誤。 – 2010-07-12 03:00:44

回答

4

在這一行:

g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(applyIngresarDados), &dados); 

你傳遞一個指針dados結構,這是堆棧分配:

struct textEntries dados; 

這是錯誤的,因爲當結構在回調中使用,包含此結構的堆棧框架將被銷燬,並可能被其他一些數據覆蓋。您試圖在回調處理程序中訪問垃圾數據。

+1

那麼這樣做的正確方法是什麼?這裏提到正確的方法很有價值。 – inckka 2016-01-26 06:37:56

1

您回調簽名應該是這樣的

gboolean appCallBack(GtkWidget*,gpointer); 

您可以強制轉換的gpointer你的類型的結構。 請使用API​​ gtk_entry_new().創建一個條目我還沒有在gtk + 2.0文檔中找到任何有關gtk_entry_new_with_max_length的參考。

GtkWidget *entry; 
entry = gtk_entry_new(); 

現在在你的appCallback函數中可以得到如下的輸入文本。

GtkWidget *entry = (GtkWidget *) callback_data; //data passed in signal connect. 

然後你可以從該條目中的文字與呼叫

gchar *text; 
text = gtk_entry_get_text(GTK_ENTRY(entry)); 

也可做適當的錯誤檢查。

或者您可以將textentries結構聲明爲指針。

+0

gtk_entry_new_with_max_length存在,但自Gtk-2.0以來不推薦使用,不應在新編寫的代碼中使用。 – 2010-07-12 04:32:38

+0

@德米特里 - 那麼在這種情況下,我認爲問題存在與回調簽名和持有小部件的指針。 – 2010-07-12 04:37:55

+0

以我所做的方式將gpointer更改爲另一種類型的指針也起作用。 – 2010-07-12 12:53:20