2013-06-28 8 views
0

저는 C로 코딩하고 Linux에서 응용 프로그램을 작성하는 데 GTK를 사용하고 구현하기 전에 Glade를 사용하여 UI를 디자인하는 방법을 가르쳐 왔습니다. 나는 데이터를 표시하기 위해 GtkListStore와 결합 된 GtkTreeView를 활용하려고 노력했지만 문제를 겪고있는 것처럼 보입니다. 내 응용 프로그램을 잘 실행하고 창과 대화 상자를 올바르게 표시 할 수는 있지만 목록 행에 프로그래밍 방식으로 데이터 행을 추가하고이를 트리 뷰에 표시하는 방법을 알 수는 없습니다. 대부분의 튜토리얼은 Glade에서 행을 만들거나 코드를 통해 전체 인터페이스를 디자인하는 것을 선호합니다. 코드를 그대로 사용하면 프로그램을 실행할 때 오류가 발생하지 않지만 GtkTreeView에 추가 된 내용을 볼 수 없습니다. 빈 줄이 추가되지 않습니다.Glmade에서 만든 프로그래밍 방식으로 GtkTreeView/GtkListStore에 데이터 추가

강제로 오류가 발생하도록 코드를 작성하면 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. 이는 포스트 버튼을 클릭 할 때마다 새 트리와 새 저장소를 만드는 것이므로 분명히 잘못되었습니다. 이는 treeview1user_data으로 보내고 on_postingButton_clicked 콜백에 쉽게 해결할 수 있습니다. 이미 dialog에서 작업 했으므로 XML에서 <signal name="clicked" handler="on_postingButton_clicked" ...>을 수정하여 object="treeview1"을 포함하기 만하면됩니다.

  2. 당신은 너무 진보적입니다. g_object_unref입니다. gtk_tree_view_get_model은 모델의 refcount를 증가시키지 않으므로 얻을 수있는 목록 저장을 참조해야합니다. main에있는 빌더를 참조 해제하는 것은 나쁜 생각 일 것입니다. 만약 당신이 그것을 주변에 전달하고 그것으로부터 객체를 검색하고 싶다면 (그리고 그것은 어쨌든 싱글 톤입니다.)

  3. 중간에 gtk-3.0 디렉토리가 없으면 #include <gtk/gtk.h>이됩니다. 컴파일없이 컴파일에 실패하면 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