我正在创建一个计算器,当在一行中查找“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”函数中声明结构。
您的
g_signal_connect
调用正在传递 GtkWidget
作为第一个参数,这是错误的,传递一个对象。
切换自:
g_signal_connect(cancelButton, "clicked", G_CALLBACK(OkButtonClicked), dialogData);
到
g_signal_connect(G_OBJECT(cancelButton), "clicked", G_CALLBACK(OkButtonClicked), dialogData);
我没有看到问题中提到的“按键处理程序”(但在这种情况下你可能会犯同样的错误)。