2013-06-28 5 views
0

Я преподаю, как программировать на C и использовать GTK для написания приложений в Linux, используя Glade для разработки пользовательского интерфейса перед его внедрением. Я пытаюсь использовать GtkTreeView вместе с GtkListStore для отображения данных, но, похоже, я сталкиваюсь с проблемами. Я могу заставить приложение запускаться нормально, и он показывает окно и диалог правильно, но я не могу понять, как программно добавлять строки данных в хранилище списков и отображать их в виде дерева; большинство учебных пособий, которые, как мне кажется, предпочитают делать строки в Glade или создавать весь интерфейс через код. С кодом, так как я не получаю никаких ошибок при запуске программы, но я ничего не вижу в GtkTreeView. Я также не вижу добавленных пустых строк.Программно добавление данных в GtkTreeView/GtkListStore, созданный в Glade 3.12.1

При написании кода для принудительной генерации ошибки, я вижу, что сигнал для postingButton подключается (я думаю), так что это должно быть хорошо. Я просто что-то пропустил в своей реальной реализации GtkTreeView. Если кто-нибудь сможет мне помочь, я бы очень признателен!

Редактировать: GtkEntries, которые присутствуют, будут реализованы позже; Я просто пытаюсь получить данные, чтобы показать вообще.

C Код:

/* I'd give objects better names normally, no worries! 
* Just goofing around for now.*/ 

#include <gtk-3.0/gtk/gtk.h> // Needed for interface. 
#include <gtk-3.0/gdk/gdk.h> 
#include <glib-2.0/glib-object.h> 

void on_mainWindow_destroy(GObject *object, gpointer user_data) 
{ 
    gtk_main_quit(); 
} 

void on_stupidButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    gtk_dialog_run(GTK_DIALOG(user_data)); 
} 

void on_postingButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    GtkListStore *liststore1; 
    GtkWidget *treeview1; // I've tried defining this as a GtkTreeView as well. 
    GtkTreeIter iter; 
    GtkBuilder *listStoreBuilder; 

    listStoreBuilder = gtk_builder_new(); 
    gtk_builder_add_from_file(listStoreBuilder, 
      "../testing_interface.glade", 0); 

    treeview1 = GTK_WIDGET(gtk_builder_get_object(listStoreBuilder, 
      "treeview1")); // I'd change this to GTK_TREE_VIEW if the 
          // above is a GtkTreeView. 
    liststore1 = GTK_LIST_STORE(
      gtk_tree_view_get_model((GtkTreeView *)treeview1)); 

    gtk_list_store_append(liststore1, &iter); 
    gtk_list_store_set(liststore1, &iter, 0, "c", 1, "d", -1); 

    gtk_builder_connect_signals(listStoreBuilder, 0); 

    g_object_unref(G_OBJECT(listStoreBuilder)); 
    g_object_unref(G_OBJECT(liststore1)); 
} 

void on_cancelButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    gtk_widget_destroy((GtkWidget *)user_data); 
} 

int main(int argc, char *argv[]) 
{ 
    GtkBuilder *builder; 
    GtkWidget *mainWindow, *dumbDialog; 
    GtkButton *stupidButton; 

    gtk_init(&argc, &argv); 

    builder = gtk_builder_new(); 
    gtk_builder_add_from_file(builder, "../testing_interface.glade", 
      0); 

    mainWindow = GTK_WIDGET(gtk_builder_get_object(builder, "mainWindow")); 
    stupidButton = GTK_BUTTON(gtk_builder_get_object(builder, "stupidButton")); 
    dumbDialog = GTK_WIDGET(gtk_builder_get_object(builder, "dumbDialog")); 

    gtk_builder_connect_signals(builder, 0); 

    g_object_unref(G_OBJECT(builder)); 
    gtk_widget_show(mainWindow); 
    gtk_main(); 

    return 0; 
} 

Glade Файл (testing_interface.glade):

<?xml version="1.0" encoding="UTF-8"?> 
<interface> 
    <!-- interface-requires gtk+ 3.0 --> 
    <object class="GtkDialog" id="dumbDialog"> 
    <property name="can_focus">False</property> 
    <property name="border_width">5</property> 
    <property name="type_hint">dialog</property> 
    <child internal-child="vbox"> 
     <object class="GtkBox" id="dialog-vbox1"> 
     <property name="can_focus">False</property> 
     <property name="orientation">vertical</property> 
     <property name="spacing">2</property> 
     <child internal-child="action_area"> 
      <object class="GtkButtonBox" id="dialog-action_area1"> 
      <property name="can_focus">False</property> 
      <property name="layout_style">end</property> 
      <child> 
       <object class="GtkButton" id="postingButton"> 
       <property name="label" translatable="yes">Post</property> 
       <property name="use_action_appearance">False</property> 
       <property name="visible">True</property> 
       <property name="can_focus">True</property> 
       <property name="receives_default">True</property> 
       <property name="use_action_appearance">False</property> 
       <signal name="clicked" handler="on_postingButton_clicked" swapped="no"/> 
       </object> 
       <packing> 
       <property name="expand">False</property> 
       <property name="fill">True</property> 
       <property name="position">0</property> 
       </packing> 
      </child> 
      <child> 
       <object class="GtkButton" id="cancelButton"> 
       <property name="label" translatable="yes">Cancel</property> 
       <property name="use_action_appearance">False</property> 
       <property name="visible">True</property> 
       <property name="can_focus">True</property> 
       <property name="receives_default">True</property> 
       <property name="use_action_appearance">False</property> 
       <signal name="clicked" handler="on_cancelButton_clicked" object="dumbDialog" swapped="no"/> 
       </object> 
       <packing> 
       <property name="expand">False</property> 
       <property name="fill">True</property> 
       <property name="position">1</property> 
       </packing> 
      </child> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="pack_type">end</property> 
      <property name="position">0</property> 
      </packing> 
     </child> 
     <child> 
      <object class="GtkBox" id="box2"> 
      <property name="visible">True</property> 
      <property name="can_focus">False</property> 
      <property name="orientation">vertical</property> 
      <child> 
       <object class="GtkEntry" id="entry1"> 
       <property name="visible">True</property> 
       <property name="can_focus">True</property> 
       <property name="invisible_char">●</property> 
       </object> 
       <packing> 
       <property name="expand">False</property> 
       <property name="fill">True</property> 
       <property name="position">0</property> 
       </packing> 
      </child> 
      <child> 
       <object class="GtkEntry" id="entry2"> 
       <property name="visible">True</property> 
       <property name="can_focus">True</property> 
       <property name="invisible_char">●</property> 
       </object> 
       <packing> 
       <property name="expand">False</property> 
       <property name="fill">True</property> 
       <property name="position">1</property> 
       </packing> 
      </child> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="position">1</property> 
      </packing> 
     </child> 
     </object> 
    </child> 
    <action-widgets> 
     <action-widget response="0">postingButton</action-widget> 
     <action-widget response="0">cancelButton</action-widget> 
    </action-widgets> 
    </object> 
    <object class="GtkListStore" id="liststore1"> 
    <columns> 
     <!-- column-name Testing --> 
     <column type="gchararray"/> 
     <!-- column-name Testing1 --> 
     <column type="gchararray"/> 
    </columns> 
    </object> 
    <object class="GtkWindow" id="mainWindow"> 
    <property name="can_focus">False</property> 
    <signal name="destroy" handler="on_mainWindow_destroy" swapped="no"/> 
    <child> 
     <object class="GtkBox" id="box1"> 
     <property name="visible">True</property> 
     <property name="can_focus">False</property> 
     <property name="orientation">vertical</property> 
     <child> 
      <object class="GtkTreeView" id="treeview1"> 
      <property name="height_request">183</property> 
      <property name="visible">True</property> 
      <property name="can_focus">True</property> 
      <property name="model">liststore1</property> 
      <child internal-child="selection"> 
       <object class="GtkTreeSelection" id="treeview-selection1"/> 
      </child> 
      <child> 
       <object class="GtkTreeViewColumn" id="testing1Col"> 
       <property name="title" translatable="yes">column</property> 
       <child> 
        <object class="GtkCellRendererText" id="cellrenderertext1"/> 
        <attributes> 
        <attribute name="text">0</attribute> 
        </attributes> 
       </child> 
       </object> 
      </child> 
      <child> 
       <object class="GtkTreeViewColumn" id="testing2Col"> 
       <property name="title" translatable="yes">column</property> 
       <child> 
        <object class="GtkCellRendererText" id="cellrenderertext2"/> 
        <attributes> 
        <attribute name="text">1</attribute> 
        </attributes> 
       </child> 
       </object> 
      </child> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="position">0</property> 
      </packing> 
     </child> 
     <child> 
      <object class="GtkButton" id="stupidButton"> 
      <property name="label" translatable="yes">button</property> 
      <property name="use_action_appearance">False</property> 
      <property name="visible">True</property> 
      <property name="can_focus">True</property> 
      <property name="receives_default">True</property> 
      <property name="use_action_appearance">False</property> 
      <signal name="clicked" handler="on_stupidButton_clicked" object="dumbDialog" swapped="no"/> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="position">1</property> 
      </packing> 
     </child> 
     </object> 
    </child> 
    </object> 
</interface> 

ответ

0

Ваш код, который добавляет строки в виде дерева, в основном хорошо, но некоторые проблемы мешают ему работать.

  1. Вы создаете и заселять новый построитель на каждом входе в on_postingButton_clicked. Это явно неверно, потому что это означает, что вы создаете новое дерево и новое хранилище при каждом нажатии кнопки «Опубликовать». Это легко установить, отправив treeview1 как user_data в обратный вызов on_postingButton_clicked. Вы делаете это уже в dialog, поэтому я просто изменил <signal name="clicked" handler="on_postingButton_clicked" ...> в вашем XML, чтобы также включить object="treeview1".

  2. Вы слишком либеральны с g_object_unref. gtk_tree_view_get_model не увеличивает коэффициент пересчета своей модели, поэтому вы не должны блокировать список, который вы получаете. Unrefing строителя в main, вероятно, плохая идея, если вы хотите передать его и извлечь из него объекты (и это все равно).

  3. Предполагается, что вы должны #include <gtk/gtk.h>, без промежуточного каталога gtk-3.0. Если ваша компиляция завершится без этого, возможно, вы неправильно настроили pkg-flags.

Здесь представлена ​​измененная версия вашего кода, которая работает для меня. Для этого требуется, чтобы XML был модифицирован, как описано выше.

/* compile with: 
    gcc -O2 -Wall glade-test.c $(pkg-config gtk+-3.0 gmodule-export-2.0 --cflags --libs) */ 

#include <gtk/gtk.h> 
#include <gdk/gdk.h> 
#include <glib-object.h> 

void on_mainWindow_destroy(GObject *object, gpointer user_data) 
{ 
    gtk_main_quit(); 
} 

void on_stupidButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    gtk_dialog_run(GTK_DIALOG(user_data)); 
} 

void on_postingButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    GtkTreeIter iter; 
    GtkTreeView *treeview1 = GTK_TREE_VIEW(user_data); 
    GtkListStore *liststore1 = GTK_LIST_STORE(gtk_tree_view_get_model(treeview1)); 

    gtk_list_store_append(liststore1, &iter); 
    gtk_list_store_set(liststore1, &iter, 0, "c", 1, "d", -1); 
} 

void on_cancelButton_clicked(GtkButton *button, gpointer *user_data) 
{ 
    gtk_widget_destroy((GtkWidget *)user_data); 
} 

int main(int argc, char *argv[]) 
{ 
    GtkBuilder *builder; 

    gtk_init(&argc, &argv); 

    builder = gtk_builder_new(); 
    gtk_builder_add_from_file(builder, "testing_interface.glade", 0); 
    gtk_builder_connect_signals(builder, 0); 
    gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(builder, "mainWindow"))); 
    g_object_unref(G_OBJECT(builder)); 
    gtk_main(); 

    return 0; 
} 
+0

Это работает здесь, спасибо @ user4815162342! Очевидно, мне еще многое предстоит узнать, спасибо за вашу помощь! – jsdewey