2010-07-12 105 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