2011-06-03 88 views
1

我正在嘗試使用GTK +爲我的音樂管理器編寫接口。該程序已成功編譯。然而,當我執行,將本機返回的錯誤:GTK +警告:無法設置父母的部件有父母

(dingo_draft:6462): Gtk-WARNING **: Can't set a parent on widget which has a parent 


(dingo_draft:6462): Gtk-CRITICAL **: gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed 
** 
Gtk:ERROR:/build/buildd/gtk+2.0-2.20.1/gtk/gtkwidget.c:8760:gtk_widget_real_map: assertion failed: (gtk_widget_get_realized (widget)) 
Aborted 


下面是程序的源代碼。請注意,這是只是用GTK +編寫的接口。我還沒有添加任何信號。我想可能有一些問題與GTK +的功能,但我無法找到在錯誤發生:

/* This is the interface design draft for the media player 
/* This does not include the signals for widgets. Just a plain draft */ 

#include <gtk/gtk.h> 
#include <gst/gst.h> 

int main(int argc, char *argv[]) { 
    /* Initialize gtk+ & gstreamer */ 
    gtk_init(&argc, &argv); 
    gst_init(&argc, &argv); 

    /* Create mainwindow (mainwindow) */ 
    GtkWidget *mainwindow; 

    mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_title(GTK_WINDOW(mainwindow), "Music Manager"); 

    /* Create the vbox containing searchbox & song list (treevbox) */ 
    GtkWidget *searchbox, *treesong, *scrollsong, *treevbox; 
    /* GtkWidget *colname, *coltime; */ 
    GtkCellRenderer *namerender, *timerender; 

    treesong = gtk_tree_view_new(); 
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treesong), FALSE); 

    namerender = gtk_cell_renderer_text_new(); 
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treesong), -1, "Songs", namerender, "text", 0, NULL); 

    timerender = gtk_cell_renderer_text_new(); 
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treesong), -1, "Time", timerender, "text", 1, NULL); 

    scrollsong = gtk_scrolled_window_new(NULL, NULL); 
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollsong), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 

    gtk_container_add(GTK_CONTAINER(scrollsong), treesong); 

    searchbox = gtk_entry_new(); 

    treevbox = gtk_vbox_new(TRUE, 0); 
    gtk_box_pack_start_defaults(GTK_BOX(treevbox), searchbox); 
    gtk_box_pack_start_defaults(GTK_BOX(treevbox), scrollsong); 

    /* Create the song info section (infohbox) */ 
    GtkWidget *songname, *songinfo, *coverart; 
    GtkWidget *infohbox, *imagevbox; 

    coverart = gtk_image_new_from_file("music-notes.png"); 
    songname = gtk_label_new("<i>Song Name</i>"); 
    songinfo = gtk_label_new("<b>Artist:</b> \n <b>Track</b> \n <b>Album</b> \n <b>Year</b> \n <b>Genre</b> \n <b>Rating</b>"); 

    infohbox = gtk_hbox_new(TRUE, 0); 
    imagevbox = gtk_vbox_new(TRUE, 0); 

    gtk_box_pack_start_defaults(GTK_BOX(imagevbox), coverart); 
    gtk_box_pack_start_defaults(GTK_BOX(imagevbox), songname); 
    gtk_box_pack_start_defaults(GTK_BOX(infohbox), imagevbox); 
    gtk_box_pack_start_defaults(GTK_BOX(infohbox), songinfo); 

    /* Create drawing area for video display (previewarea) */ 
    GtkWidget *previewarea; 

    previewarea = gtk_drawing_area_new(); 
    gtk_widget_set_size_request(previewarea, 300, 200); 

    /* Create actions tree view (ltreeview) */ 
    enum { 
    COL_ICON = 0, 
    COL_ACTION, 
    NUM_COLS 
    }; 

    GtkCellRenderer *lrenderer; 
    GtkTreeModel *lmodel; 
    GtkWidget *ltreeview; 
    GtkListStore *lliststore; 
    GtkTreeIter liter; 

    ltreeview = gtk_tree_view_new(); 

    lrenderer = gtk_cell_renderer_pixbuf_new(); 
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(ltreeview), -1, "Icon", lrenderer, "pixbuf", COL_ICON, NULL); 

    lrenderer = gtk_cell_renderer_text_new(); 
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(ltreeview), -1, "Actions", lrenderer, "text", COL_ACTION, NULL); 

    lliststore = gtk_list_store_new(NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING); 

    gtk_list_store_append(lliststore, &liter); 
    gtk_list_store_set(lliststore, &liter, COL_ICON, gdk_pixbuf_new_from_file("now-playing.png", NULL), COL_ACTION, "Now Playing", -1); 

    gtk_list_store_append(lliststore, &liter); 
    gtk_list_store_set(lliststore, &liter, COL_ICON, gdk_pixbuf_new_from_file("music.png", NULL), COL_ACTION, "Music", -1); 

    gtk_list_store_append(lliststore, &liter); 
    gtk_list_store_set(lliststore, &liter, COL_ICON, gdk_pixbuf_new_from_file("video.png", NULL), COL_ACTION, "Videos", -1); 

    gtk_list_store_append(lliststore, &liter); 
    gtk_list_store_set(lliststore, &liter, COL_ICON, gdk_pixbuf_new_from_file("playlist.png", NULL), COL_ACTION, "Playlists", -1); 

    lmodel = GTK_TREE_MODEL(lliststore); 

    gtk_tree_view_set_model(GTK_TREE_VIEW(ltreeview), lmodel); 

    /* g_object_unref(lmodel); */ 

    /* Create the top control bar (controlhbox) */ 
    GtkWidget *prevbutton, *nextbutton, *hscale, *cursong; 
    GtkWidget *curpos, *duration, *volumebutton, *playbutton; 
    GtkAdjustment *progress, *volumeadj; 
    GtkWidget *buttonhbox, *proghbox, *infovbox, *controlhbox; 

    prevbutton = gtk_button_new(); 
    gtk_button_set_image(GTK_BUTTON(prevbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS, GTK_ICON_SIZE_SMALL_TOOLBAR)); 

    playbutton = gtk_button_new(); 
    gtk_button_set_image(GTK_BUTTON(playbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DND)); 

    nextbutton = gtk_button_new(); 
    gtk_button_set_image(GTK_BUTTON(nextbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_SMALL_TOOLBAR)); 

    progress = GTK_ADJUSTMENT(gtk_adjustment_new(0.00, 0.00, 0.00, 0.00, 0.00, 0.00)); 
    hscale = gtk_hscale_new(progress); 
    gtk_scale_set_draw_value(GTK_SCALE(hscale), FALSE); 
    gtk_widget_set_size_request(hscale, 500, NULL); 

    cursong = gtk_label_new("Song's Name"); 
    curpos = gtk_label_new("0:00"); 
    duration = gtk_label_new("0:00"); 

    volumebutton = gtk_volume_button_new(); 
    volumeadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.70, 0.00, 1.00, 0.01, 0.00, 0.00)); 
    gtk_scale_button_set_adjustment(GTK_SCALE_BUTTON(volumebutton), volumeadj); 
    gtk_widget_set_size_request(volumebutton, 32, 32); 

    buttonhbox = gtk_hbox_new(TRUE, 0); 
    gtk_box_pack_start_defaults(GTK_BOX(buttonhbox), prevbutton); 
    gtk_box_pack_start_defaults(GTK_BOX(buttonhbox), playbutton); 
    gtk_box_pack_start_defaults(GTK_BOX(buttonhbox), nextbutton); 

    proghbox = gtk_hbox_new(TRUE, 0); 
    gtk_box_pack_start_defaults(GTK_BOX(proghbox), curpos); 
    gtk_box_pack_start_defaults(GTK_BOX(proghbox), hscale); 
    gtk_box_pack_start_defaults(GTK_BOX(proghbox), duration); 

    controlhbox = gtk_hbox_new(TRUE, 0); 
    gtk_box_pack_start_defaults(GTK_BOX(controlhbox), buttonhbox); 
    gtk_box_pack_start_defaults(GTK_BOX(controlhbox), proghbox); 
    gtk_box_pack_start_defaults(GTK_BOX(controlhbox), volumebutton); 

    /* Create panes (tophpaned) and pack widgets into this (tophpaned)*/ 
    GtkWidget *tophpaned, *subhpaned, *vpaned; 

    vpaned = gtk_vpaned_new(); 
    gtk_paned_add1(GTK_PANED(vpaned), songinfo); 
    gtk_paned_add2(GTK_PANED(vpaned), previewarea); 

    subhpaned = gtk_hpaned_new(); 
    gtk_paned_pack1(GTK_PANED(subhpaned), vpaned, TRUE, TRUE); 
    gtk_paned_pack2(GTK_PANED(subhpaned), treevbox, TRUE, TRUE); 

    tophpaned = gtk_hpaned_new(); 
    gtk_paned_pack1(GTK_PANED(tophpaned), ltreeview, TRUE, TRUE); 
    gtk_paned_pack2(GTK_PANED(tophpaned), subhpaned, TRUE, TRUE); 

    /* Create an topvbox to pack all the above stuffs in, */ 
    /* then add topvbox to window */ 
    GtkWidget *topvbox; 

    topvbox = gtk_vbox_new(TRUE, 0); 
    gtk_box_pack_start_defaults(GTK_BOX(topvbox), controlhbox); 
    gtk_box_pack_start_defaults(GTK_BOX(topvbox), tophpaned); 

    gtk_container_add(GTK_CONTAINER(mainwindow), topvbox); 

    /* Show all widgets & draw the interface */ 
    gtk_widget_show_all(mainwindow); 

    gtk_main(); 

    return 0; 
} 


謝謝你回答我的問題!我感謝你的幫助!在調試器(GDB)

+0

'scrollsong'是在'treesong'加入之前初始化的嗎? – Messa 2011-06-03 09:49:47

回答

3

您試圖將songinfo放入兩個不同的容器中:分成infohboxvpaned

正如Havoc所說,gdb可以幫助您找到給出警告的確切代碼。我可以提供兩個附加建議:

  • 在Glade中構建您的接口。這將幫助您在構建它時看到它發生了什麼。它還會使其更易於維護,並幫助您避免這些類型的錯誤。
  • 在您使用大代碼轉儲問一個關於堆棧溢出的問題之前,嘗試製作一個能夠重現問題的最小程序。通常你會在你完成這件事的時候自己解決問題。
4

運行,設置在第一警告消息斷點(曾經被g_logv所有警告經歷,但是如果需要檢查油嘴 源),然後輸入「BT」在gdb時它打破了看哪條線引起警告。

另一種方法是在環境中設置G_DEBUG=fatal-warnings,然後再次使用gdb,不需要斷點時只需在應用程序崩潰時進行跟蹤警告。

另一個可能的步驟是在Valgrind中運行,並在內存訪問或寫入不良時修復投訴。