Ошибка сегментации GtkStack - PullRequest
       37

Ошибка сегментации GtkStack

0 голосов
/ 01 января 2019

Я сделал простую программу, чтобы научиться работать с виджетом GtkStack.Программа должна переключать страницы стека при нажатии кнопки.Однако, когда кнопка нажата, программа завершается с ошибкой segmentation fault Я очень плохо знаком с C и GTK и не могу понять, почему это не работает.

ОС: 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;
}

Glade 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`

1 Ответ

0 голосов
/ 01 января 2019

Отладчик сообщает вам, где происходит ошибка сегментации:

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, и он будет работать.

...