GtkStack 分段错误
GtkStack segmentation fault
我制作了一个简单的程序来学习如何使用 GtkStack 小部件。该程序应该在单击按钮时切换堆栈页面。但是,当单击该按钮时,程序终止并出现错误 segmentation fault
我对 C 和 GTK 都很陌生,似乎无法理解为什么这不起作用。
OS:Debian 9.6 与 Gnome 3.22.2
C代码:
#include <gtk/gtk.h>
typedef struct _MyStruct
{
GtkWidget *mainWindow;
GtkWidget *myStack;
GtkWidget *page0;
GtkWidget *page1;
GtkWidget *buttonPage0;
GtkWidget *buttonPage1;
} MyStruct;
static void clickedButtonPage0(GtkWidget *widget, MyStruct *mrp)
{
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page1);
}
static void clickedButtonPage1(GtkWidget *widget, MyStruct *mrp)
{
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page0);
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
MyStruct mrp;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "stackTest.glade", NULL);
mrp.mainWindow = GTK_WIDGET(gtk_builder_get_object(builder, "myWindow"));
g_signal_connect(mrp.mainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
mrp.myStack = GTK_WIDGET(gtk_builder_get_object(builder, "myStack"));
mrp.page0 = GTK_WIDGET(gtk_builder_get_object(builder, "page0"));
mrp.page1 = GTK_WIDGET(gtk_builder_get_object(builder, "page1"));
mrp.buttonPage0 = GTK_WIDGET(gtk_builder_get_object(builder, "buttonPage0"));
mrp.buttonPage1 = GTK_WIDGET(gtk_builder_get_object(builder, "buttonPage1"));
g_signal_connect(mrp.buttonPage0, "clicked", G_CALLBACK(clickedButtonPage0), NULL);
g_signal_connect(mrp.buttonPage1, "clicked", G_CALLBACK(clickedButtonPage1), NULL);
g_object_unref(builder);
gtk_window_set_default_size(GTK_WINDOW(mrp.mainWindow), 600, 400);
gtk_window_set_title(GTK_WINDOW(mrp.mainWindow), "GtkStack Test");
gtk_widget_show_all(mrp.mainWindow);
gtk_main();
return 0;
}
格莱德 XLM:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="myWindow">
<property name="can_focus">False</property>
<child>
<object class="GtkStack" id="myStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="page0">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="lblPage0">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">I am page 0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonPage0">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page0</property>
<property name="title" translatable="yes">page0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="page1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="lblPage1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">I am Page 1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonPage1">
<property name="label" translatable="yes">Home</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="title" translatable="yes">page1</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
编译使用:
gcc stackTest.c -o stackTest `pkg-config --cflags --libs gtk+-3.0`
调试器告诉你段错误发生的位置:
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page1);
唯一使用的变量是mrp
。这个变量是NULL
.
它是NULL
因为你只提供了一个NULL
指针:
g_signal_connect(mrp.buttonPage0, "clicked", G_CALLBACK(clickedButtonPage0), NULL);
g_signal_connect(mrp.buttonPage1, "clicked", G_CALLBACK(clickedButtonPage1), NULL);
将 NULL
替换为 &mrp
即可。
我制作了一个简单的程序来学习如何使用 GtkStack 小部件。该程序应该在单击按钮时切换堆栈页面。但是,当单击该按钮时,程序终止并出现错误 segmentation fault
我对 C 和 GTK 都很陌生,似乎无法理解为什么这不起作用。
OS:Debian 9.6 与 Gnome 3.22.2
C代码:
#include <gtk/gtk.h>
typedef struct _MyStruct
{
GtkWidget *mainWindow;
GtkWidget *myStack;
GtkWidget *page0;
GtkWidget *page1;
GtkWidget *buttonPage0;
GtkWidget *buttonPage1;
} MyStruct;
static void clickedButtonPage0(GtkWidget *widget, MyStruct *mrp)
{
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page1);
}
static void clickedButtonPage1(GtkWidget *widget, MyStruct *mrp)
{
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page0);
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
MyStruct mrp;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "stackTest.glade", NULL);
mrp.mainWindow = GTK_WIDGET(gtk_builder_get_object(builder, "myWindow"));
g_signal_connect(mrp.mainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
mrp.myStack = GTK_WIDGET(gtk_builder_get_object(builder, "myStack"));
mrp.page0 = GTK_WIDGET(gtk_builder_get_object(builder, "page0"));
mrp.page1 = GTK_WIDGET(gtk_builder_get_object(builder, "page1"));
mrp.buttonPage0 = GTK_WIDGET(gtk_builder_get_object(builder, "buttonPage0"));
mrp.buttonPage1 = GTK_WIDGET(gtk_builder_get_object(builder, "buttonPage1"));
g_signal_connect(mrp.buttonPage0, "clicked", G_CALLBACK(clickedButtonPage0), NULL);
g_signal_connect(mrp.buttonPage1, "clicked", G_CALLBACK(clickedButtonPage1), NULL);
g_object_unref(builder);
gtk_window_set_default_size(GTK_WINDOW(mrp.mainWindow), 600, 400);
gtk_window_set_title(GTK_WINDOW(mrp.mainWindow), "GtkStack Test");
gtk_widget_show_all(mrp.mainWindow);
gtk_main();
return 0;
}
格莱德 XLM:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="myWindow">
<property name="can_focus">False</property>
<child>
<object class="GtkStack" id="myStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="page0">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="lblPage0">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">I am page 0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonPage0">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page0</property>
<property name="title" translatable="yes">page0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="page1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="lblPage1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">I am Page 1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonPage1">
<property name="label" translatable="yes">Home</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="title" translatable="yes">page1</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
编译使用:
gcc stackTest.c -o stackTest `pkg-config --cflags --libs gtk+-3.0`
调试器告诉你段错误发生的位置:
gtk_stack_set_visible_child (GTK_STACK(mrp->myStack), mrp->page1);
唯一使用的变量是mrp
。这个变量是NULL
.
它是NULL
因为你只提供了一个NULL
指针:
g_signal_connect(mrp.buttonPage0, "clicked", G_CALLBACK(clickedButtonPage0), NULL);
g_signal_connect(mrp.buttonPage1, "clicked", G_CALLBACK(clickedButtonPage1), NULL);
将 NULL
替换为 &mrp
即可。