GTK +警告:无法在具有父级的窗口小部件上设置父级

时间:2011-06-03 06:43:50

标签: c++ c 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;
}


谢谢你回答我的问题!感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

在调试器(gdb)中运行,在第一个警告消息上设置断点(以前是g_logv所有警告都经过,但检查glib 如果需要,请在gdb中输入“bt”,以便查看哪一行导致警告。

另一种方法是在环境中设置G_DEBUG=fatal-warnings,然后再次使用gdb,当应用程序崩溃警告时,不需要断点。

另一个可能的步骤是在Valgrind中运行并在内存访问或写入错误时修复其抱怨。

答案 1 :(得分:4)

您正试图将songinfo放入两个不同的容器中:infohboxvpaned

正如Havoc所说,gdb可以帮助您找到给您警告的确切代码。我可以提供两个额外的建议:

  • 在Glade中构建您的界面。这将帮助您在构建时查看正在发生的事情。它还可以使其更易于维护,并帮助您避免这些错误。
  • 在使用大型代码转储在Stack Overflow上提出问题之前,请尝试制作一个可以重现问题的最小程序。通常,在您完成此操作时,您将自己解决问题。