GTK - Retrieve multiple values from widgets on button press

回眸只為那壹抹淺笑 提交于 2020-03-25 12:34:01

问题


This is a follow up question to my previous question here: GTK Retrieve values from multiple widgets on button press

I am still trying to solve the same issue, however have implemented suggestions from the previous question's responses.

Here is my full code:

#include <gtk/gtk.h>

struct data {
    GtkEntry *hash;
    GtkWidget *hashType;
};

static void queue_hash (GtkButton *button, gpointer user_data) {

    struct data *dataStruct = user_data;

    GtkEntry *hashWid = dataStruct->hash;
    GtkWidget *hashTypeWid = dataStruct->hashType;

    const char* hash = gtk_entry_get_text(hashWid);
    char* hashType = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(hashTypeWid));

    g_print ("Queue Hash: %s    %s\n", hash, hashType);
}


static void init(GtkApplication* app, gpointer user_data) {
    GtkWidget *window;
    GtkWidget *window_fixed;
    GtkWidget *nodeListBox;
    GtkWidget *hashListBox;
    GtkWidget *queueButtonBox;
    GtkWidget *queueButton;
    GtkWidget *hashEntry;
    GtkWidget *hashSelect;
    GtkWidget *remHashButton;
    GtkWidget *remHashButtonBox;
    GtkWidget *logBox;
    GtkWidget *nodesLabel;
    GtkWidget *hashLabel;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "HashCrack Server");
    gtk_window_set_default_size (GTK_WINDOW (window), 1000, 435);
    gtk_window_set_resizable (GTK_WINDOW(window), FALSE);

    window_fixed = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), window_fixed);

    queueButtonBox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    queueButton = gtk_button_new_with_label("Queue Hash");
    remHashButtonBox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    remHashButton = gtk_button_new_with_label("Remove Selected Hash");

    nodeListBox = gtk_list_box_new();
    gtk_widget_set_size_request(nodeListBox, 250, 365);
    hashListBox = gtk_list_box_new();
    gtk_widget_set_size_request(hashListBox, 250, 325);

    nodesLabel = gtk_label_new("Connected Nodes");
    gtk_label_set_markup(GTK_LABEL(nodesLabel), "<span font_desc=\"20.0\">Connected Nodes</span>");
    gtk_fixed_put(GTK_FIXED(window_fixed), nodesLabel, 40, 15);

    hashLabel = gtk_label_new("Connected Nodes");
    gtk_label_set_markup(GTK_LABEL(hashLabel), "<span font_desc=\"20.0\">Queued Hashes</span>");
    gtk_fixed_put(GTK_FIXED(window_fixed), hashLabel, 755, 15);

    hashEntry = gtk_entry_new();
    gtk_widget_set_size_request(hashEntry, 290, 33);
    gtk_fixed_put(GTK_FIXED(window_fixed), hashEntry, 300, 75);

    hashSelect = gtk_combo_box_text_new();
    gtk_widget_set_size_request(hashSelect, 102, 25);
    gtk_fixed_put(GTK_FIXED(window_fixed), hashSelect, 595, 75);
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hashSelect), "MD5");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hashSelect), "SHA1");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hashSelect), "ROT16");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hashSelect), "###");

    gtk_widget_set_size_request(queueButtonBox, 390, 25);
    gtk_widget_set_size_request(queueButton, 390, 25);
    gtk_fixed_put(GTK_FIXED(window_fixed), queueButtonBox, 300, 120);

    struct data *cb_data = g_new0(struct data, 1);
    cb_data->hash = GTK_ENTRY(hashEntry);
    cb_data->hashType = hashSelect;
    g_signal_connect_swapped(queueButton, "clicked", G_CALLBACK (queue_hash), cb_data);

    logBox = gtk_text_view_new();
    gtk_widget_set_size_request(logBox, 400, 240);
    gtk_fixed_put(GTK_FIXED(window_fixed), logBox, 300, 175);

    gtk_widget_set_size_request(remHashButtonBox, 200, 25);
    gtk_widget_set_size_request(remHashButton, 200, 25);
    gtk_fixed_put(GTK_FIXED(window_fixed), remHashButtonBox, 750, 390);

    gtk_container_add(GTK_CONTAINER(queueButtonBox), queueButton);
    gtk_container_add(GTK_CONTAINER(remHashButtonBox), remHashButton);
    gtk_fixed_put(GTK_FIXED(window_fixed), nodeListBox, 25, 50);
    gtk_fixed_put(GTK_FIXED(window_fixed), hashListBox, 725, 50);

    gtk_widget_show_all(window);
}

int main(int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new ("com.sds.hashcrack", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (init), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

And when I press my button to try and retrieve the values, I get this error:

(SDS-CW:25413): Gtk-CRITICAL **: 19:18:19.125: gtk_entry_get_text: assertion 'GTK_IS_ENTRY (entry)' failed

Any help would be greatly appreciated, thanks.


回答1:


You misinterpreted how g_signal_connect_swapped works.

If you provide a function that matches the signature given in the manual, you mustn't use g_signal_connect_swapped! Use g_signal_connect instead.

If for some reasons you must use a different function, that only takes 1 parameter that matches second parameter from the defined signature, (because you use some library function) then you can use g_signal_connect_swapped.

In the linkes question my answer tells you to fix signature or use g_signal_connect_swapped. Not both.

A correct combination is:

static void queue_hash (GtkButton *button, gpointer user_data) {

    struct data *dataStruct = user_data;
...
}

g_signal_connect(queueButton, "clicked", G_CALLBACK (queue_hash), cb_data);

or

static void queue_hash (struct data *dataStruct) {
...
}

g_signal_connect_swapped(queueButton, "clicked", G_CALLBACK (queue_hash), cb_data);

You can easily detect this by running your program in a debugger and look at the address of cb_data in init and button + user_data in your callback function. Running your program in a debugger is generally a good idea in many cases.



来源:https://stackoverflow.com/questions/60747138/gtk-retrieve-multiple-values-from-widgets-on-button-press

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!