Как получить входные значения, используя G_CALLBACK, используя GTK в C - PullRequest
0 голосов
/ 28 января 2019

Я настраиваю окно входа в систему для чего-то, что мне нужно в школьном проекте, используя GTK, CodeBlocks и Glade.Это простая форма, имя пользователя, пароль и кнопка подключения.Проблема в том, что я не могу получить значение входных данных, потому что я не могу отправить свой конструктор другой функции, используя обратные вызовы.Я пытаюсь объяснить это как можно проще, извините за мой плохой английский.

void verifyConnect(GtkButton *button, gpointer *builder){
    GtkWidget *passwordInput;
    GtkWidget *usernameInput;

    passwordInput = GTK_WIDGET(gtk_builder_get_object(*builder, "passwordInput"));
    usernameInput = GTK_WIDGET(gtk_builder_get_object(*builder, "usernameInput"));

    const gchar *text1 = gtk_entry_get_text(GTK_ENTRY(passwordInput));
    const gchar *text2 = gtk_entry_get_text(GTK_ENTRY(usernameInput));

    g_print("Username : %s\n",text2);
    g_print("Password : %s\n",text1);
}


void connectUser(){
    GtkWidget *window;
    GtkWidget *connectButton;

    GtkBuilder *gtkBuilder = gtk_builder_new();
    gtk_builder_add_from_file(gtkBuilder, "loginWindow.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "loginWindow"));

    connectButton = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "connectButton"));
    g_signal_connect (connectButton, "clicked",G_CALLBACK(verifyConnect),&gtkBuilder);

    g_object_unref(G_OBJECT(gtkBuilder));

    gtk_widget_show(GTK_WIDGET(window));
}

Пока я получаю эту ошибку при нажатии на кнопку подключения.Я знаю, что это за ошибка, я просто не знаю, как получить моего компоновщика в функции verifyConnect:

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_builder_get_object: assertion `GTK_IS_BUILDER (builder)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_builder_get_object: assertion `GTK_IS_BUILDER (builder)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed
Username : (null)
Password : (null)

1 Ответ

0 голосов
/ 29 января 2019

Преступник здесь:

g_signal_connect (connectButton, "clicked",G_CALLBACK(verifyConnect),&gtkBuilder);

Переменная gtkBuilder уже является указателем, поэтому передача ее адреса в g_signal_connect() в конечном итоге делает соответствующий аргумент обратного вызова указателем на указатель .Это было бы все хорошо и здорово, за исключением одной маленькой детали: адрес памяти, который вы передали, указывает на автоматическую переменную.Автоматические переменные хранятся в стеке и освобождаются, когда возвращается функция, использующая их.После этого другие функции могут выделить то же пространство для своих нужд и перезаписать его.

Вот что вам нужно сделать, чтобы решить эту проблему:

void verifyConnect(GtkButton *button, GtkBuilder *builder){
    GtkWidget *passwordInput;
    GtkWidget *usernameInput;

    passwordInput = GTK_WIDGET(gtk_builder_get_object(builder, "passwordInput"));
    usernameInput = GTK_WIDGET(gtk_builder_get_object(builder, "usernameInput"));

    const gchar *text1 = gtk_entry_get_text(GTK_ENTRY(passwordInput));
    const gchar *text2 = gtk_entry_get_text(GTK_ENTRY(usernameInput));

    g_print("Username : %s\n",text2);
    g_print("Password : %s\n",text1);
}


void connectUser(){
    GtkWidget *window;
    GtkWidget *connectButton;

    GtkBuilder *gtkBuilder = gtk_builder_new();
    gtk_builder_add_from_file(gtkBuilder, "loginWindow.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "loginWindow"));

    connectButton = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "connectButton"));
    g_signal_connect(connectButton, "clicked", G_CALLBACK(verifyConnect), gtkBuilder);

    g_object_unref(G_OBJECT(gtkBuilder));

    gtk_widget_show(GTK_WIDGET(window));
}

Когда аргументпередается по значению, которое перестает зависеть от того, что хранится в его прежнем местоположении.

… aaa и Кстати, вы действительно уверены, что вам нужно освободить gtkBuilder внутри connectUser()?Вы также используете его в verifyConnect(), поэтому вам, вероятно, придется освободить его в конце verifyConnect(), а не в конце connectUser().

...