2013-06-28 37 views
0

我一直在教自己如何在C中編寫代碼並利用GTK在Linux中編寫應用程序,使用Glade在實現它之前設計UI。我一直在試圖利用GtkTreeView與GtkListStore結合顯示數據,但我似乎遇到了問題。我可以讓我的應用程序正常啓動,並且正確顯示窗口和對話框,但我無法弄清楚如何以編程方式向List Store添加數據行,並讓它們出現在樹視圖中;我發現大多數教程似乎都傾向於在Glade中創建行,或者通過代碼設計整個接口。使用代碼時,我在運行程序時沒有收到任何錯誤,但是我看不到在GtkTreeView中添加的任何內容。我沒有看到任何空行被添加。以編程方式將數據添加到在Glade中創建的GtkTreeView/GtkListStore 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; 
} 

格萊德文件(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_dataon_postingButton_clicked回調來解決。你已經在dialog中這樣做了,所以我只是在你的XML中修改了<signal name="clicked" handler="on_postingButton_clicked" ...>以包含object="treeview1"

  2. 你對g_object_unref太自由了。 gtk_tree_view_get_model不會增加其模型的refcount,因此您不應該取消您獲得的liststore。如果你想傳遞它並從中檢索對象(無論如何它都是單例),那麼解開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

相關問題