GTK - 按下按钮时从小部件中检索多个值

GTK - Retrieve multiple values from widgets on button press

这是我之前问题的后续问题:

我仍在努力解决同样的问题,但是已经实施了上一个问题的回复中的建议。

这是我的完整代码:

#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;
}

当我按下按钮尝试检索值时,出现此错误:

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

非常感谢任何帮助,谢谢。

您误解了 g_signal_connect_swapped 的工作原理。

如果您提供的函数与手册中给出的签名相匹配,则不得使用g_signal_connect_swapped!请改用 g_signal_connect

如果由于某些原因你必须使用不同的函数,它只需要 1 个参数匹配定义签名中的第二个参数,(因为你使用了一些库函数)那么你可以使用 g_signal_connect_swapped.

在链接问题中,我的回答告诉您修复签名 使用 g_signal_connect_swapped。两者都不是。

正确的组合是:

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);

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

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

您可以通过 运行 您的程序在调试器中轻松检测到这一点,并查看 initbutton + user_datacb_data 的地址在你的回调函数中。 运行 在很多情况下,调试器中的程序通常是个好主意。