GTK+ / C:错误:“gtk_entry_get_text:通过“g_signal_connect”将结构传递给函数时断言“GTK_IS_ENTRY(条目)”失败”

问题描述 投票:0回答:1

我正在创建一个计算器,当在一行中查找“x”时,应该询问“x”的值。我正在创建一个附加窗口,其中包含“输入”和两个按钮“确定”和“取消”。 当我通过 g_signal_connect 按键处理程序传递包含 GtkWidget *entry 和 gchar *xValue[255] 的结构时,访问条目时函数内部会发生以下错误:“gtk_entry_get_text:断言‘GTK_IS_ENTRY (entry)’失败”。

// My structs

typedef struct GlobalData
{
    GtkWidget *entry;
    GtkWidget *window;
} GlobalStruct;

typedef struct DialogData
{
    GtkWidget *dialogEntry;
    gchar xValue[255];
} DialogStruct;
gint main(gint argc, gchar **argv)
{
    gtk_init(&argc, &argv);

    GlobalStruct globalData;
    
    CreateWindow(&globalData);

    gtk_main();

    return 0;
}

void CreateWindow(GlobalStruct *globalData)
{
    GtkWidget *button;
    GtkWidget *calcGrid;

    globalData->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(globalData->window), "SmartCalc_v1.0");
    gtk_window_set_default_size(GTK_WINDOW(globalData->window), 500, 500);

    g_signal_connect(globalData->window, "destroy", G_CALLBACK(OnWindowClosed), NULL);

    gtk_container_set_border_width(GTK_CONTAINER(globalData->window), 10);

    gchar *calcButton[] = {
        "atan", "^", "sqrt", "(", ")",
        "tan", "+", "-", "*", "/",
        "acos", "7", "8", "9", "mod",
        "asin", "4", "5", "6", "log",
        "cos", "1", "2", "3", "ln",
        "sin", "x", "0", ".", "="};

    calcGrid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(globalData->window), calcGrid);

    globalData->entry = gtk_entry_new();
    gtk_grid_attach(GTK_GRID(calcGrid), globalData->entry, 0, 0, 5, 1);
    gtk_widget_set_hexpand(globalData->entry, TRUE);
    gtk_widget_set_vexpand(globalData->entry, TRUE);

    gint gridWidth = 5, gridHeight = 8, buttonIndex = 0;

    for (gint i = 1; i < gridHeight - 1; i++)
    {
        for (gint j = 0; j < gridWidth; j++)
        {
            button = gtk_button_new_with_label(calcButton[buttonIndex++]);
            gtk_grid_attach(GTK_GRID(calcGrid), button, j, i, 1, 1);
            gtk_widget_set_hexpand(button, TRUE);
            gtk_widget_set_vexpand(button, TRUE);
            g_signal_connect(button, "clicked", G_CALLBACK(ButtonClicked), globalData);
        }
    }

    button = gtk_button_new_with_label("Delete");
    gtk_grid_attach(GTK_GRID(calcGrid), button, 0, gridHeight - 1, 5, 1);
    gtk_widget_set_hexpand(button, TRUE);
    gtk_widget_set_vexpand(button, TRUE);
    g_signal_connect(button, "clicked", G_CALLBACK(ButtonClicked), globalData);

    gtk_grid_set_row_spacing(GTK_GRID(calcGrid), 10);
    gtk_grid_set_column_spacing(GTK_GRID(calcGrid), 10);

    gtk_widget_show_all(globalData->window);
}

void ButtonClicked(GtkWidget *button, gpointer data)
{
    GlobalStruct *globalData = (GlobalStruct *)data;
    GtkEntry *entry = GTK_ENTRY(globalData->entry);

    const gchar *buttonLabel = gtk_button_get_label(GTK_BUTTON(button));
    const gchar *currentText = gtk_entry_get_text(entry);

    if (!g_strcmp0(buttonLabel, "Delete"))
    {
        gtk_entry_set_text(entry, "");
    }
    else if (!g_strcmp0(buttonLabel, "="))
    {
        gchar answer[255] = {0};
        GetAnswer(currentText, answer, globalData);
        g_print("\nBefore inserting into entry\n");
        gtk_entry_set_text(entry, (const gchar *)answer);
        g_print("\nAfter inserting into entry\n");
        // g_free((gchar *)answer);
        g_print("\nAfter freeing the answer array\n");
    }
    else
    {
        gchar *newText = g_strdup_printf("%s%s", currentText, buttonLabel);
        gtk_entry_set_text(entry, newText);
        g_free(newText);
    }
}

void CreateDialogWindow(GlobalStruct *globalData, DialogStruct *dialogData)
{
    GtkWidget *dialogWindow;
    GtkWidget *dialogGrid;
    
    GtkWidget *cancelButton;
    GtkWidget *okButton;

    // Creating the dialog window
    dialogWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(dialogWindow), "Enter the value of x");
    gtk_window_set_default_size(GTK_WINDOW(dialogWindow), 300, 200);
    gtk_window_set_transient_for(GTK_WINDOW(dialogWindow), GTK_WINDOW(globalData->window));

    // Creating a grid for placing widgets
    dialogGrid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(dialogWindow), dialogGrid);

    // Creating an input widget (entry)
    dialogData->dialogEntry = gtk_entry_new();
    gtk_grid_attach(GTK_GRID(dialogGrid), dialogData->dialogEntry, 0, 0, 2, 1);
    gtk_widget_set_hexpand(dialogData->dialogEntry, TRUE);
    gtk_widget_set_vexpand(dialogData->dialogEntry, TRUE);
    
    // Initializing the string in the DialogStruct structure
    g_strlcpy(dialogData->xValue, "", sizeof(dialogData->xValue));

    // Creating the "OK" button
    okButton = gtk_button_new_with_label("OK");
    g_signal_connect(okButton, "clicked", G_CALLBACK(OkButtonClicked), dialogData);
    gtk_grid_attach(GTK_GRID(dialogGrid), okButton, 0, 1, 1, 1);
    gtk_widget_set_hexpand(okButton, TRUE);
    gtk_widget_set_vexpand(okButton, TRUE);

    // Creating the "Cancel" button
    cancelButton = gtk_button_new_with_label("Cancel");
    g_signal_connect(cancelButton, "clicked", G_CALLBACK(OkButtonClicked), dialogData);
    gtk_grid_attach(GTK_GRID(dialogGrid), cancelButton, 1, 1, 1, 1);
    gtk_widget_set_hexpand(cancelButton, TRUE);
    gtk_widget_set_vexpand(cancelButton, TRUE);

    // Setting the spacing between widgets in the grid
    gtk_grid_set_row_spacing(GTK_GRID(dialogGrid), 10);
    gtk_grid_set_column_spacing(GTK_GRID(dialogGrid), 10);

    // Showing all widgets of the dialog window
    gtk_widget_show_all(dialogWindow);
}

// Implementation of the function handling the "OK" button click
void OkButtonClicked(GtkWidget *button, gpointer data)
{
    DialogStruct *dialogData = (DialogStruct *)data;

    const gchar *entryText = gtk_entry_get_text(GTK_ENTRY(dialogData->dialogEntry));
    g_print("Entry Content: %s\n", entryText);

    // Additional processing of the entryText value can be done here
    // For example, convert it to a number and use it further.
}

void GetAnswer(const gchar *inputText, gchar *answer, GlobalStruct *globalData)
{
    Array inputArray;
    CreateArray(&inputArray);
    // Convert the expression string to a structure
    ConvertToArray(&inputArray, inputText);
    g_print("\nInfixArray:\n");
    PrintPolish(&inputArray);
    g_print("\n");
    gboolean xFlag = false; // Flag indicating the presence of "x" in the expression
    // Check the received expression for mathematical correctness
    if (CheckInfix(&inputArray, &xFlag))
    {
        if (xFlag)
        {
            // Find "x" in inputArray and replace it with the requested value
            g_print("\nFound \"x\"\n");
            DialogStruct dialogData;
            CreateDialogWindow(globalData, &dialogData);
        }
    }
}

我尝试将“g_signal_connect”更改为“g_signal_connect_swapped”和“g_signal_connect_data”,没有任何变化。我尝试在“CreateDialogWindow”或“buttonClicked”函数中声明结构。

c user-interface struct callback gtk
1个回答
0
投票

您的

g_signal_connect
调用正在传递
GtkWidget
作为第一个参数,这是错误的,传递一个对象。

切换自:

g_signal_connect(cancelButton, "clicked", G_CALLBACK(OkButtonClicked), dialogData);

g_signal_connect(G_OBJECT(cancelButton), "clicked", G_CALLBACK(OkButtonClicked), dialogData);

我没有看到问题中提到的“按键处理程序”(但在这种情况下你可能会犯同样的错误)。

© www.soinside.com 2019 - 2024. All rights reserved.