【问题标题】:Remove GTK+ container children, repopulate it, then refresh删除 GTK+ 容器子项,重新填充它,然后刷新
【发布时间】:2012-02-29 19:45:45
【问题描述】:

我遇到了 GTK+ C 应用程序的问题。我有一个容器,在启动应用程序时,它包含一个按钮。在运行期间,用户交互必须使此小部件包含更多。
我需要编写一个函数来删除所有“旧”内部按钮,然后从列表中添加所有按钮,最后刷新视图。这就是我正在写的内容,但缺少某些部分(TODO)

void refresh_sequence_panel() 
{
    GSList* iterator = NULL;
    GtkWidget* button;

    // TODO: Here the container must be empty

    // Now add all the buttons
    for (iterator = steps; iterator; iterator = iterator->next) {
       button = gtk_button_new_from_stock(GTK_STOCK_ADD);
       gtk_widget_set_size_request(button, SEQ_BUTTON_W, SEQ_BUTTON_H);
       gtk_box_pack_start(GTK_BOX(sequence_panel), button, FALSE, FALSE, 5);
       handler_id = g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(seq_popup), GTK_BOX(sequence_panel));
    }

    // TODO: Now refresh the view, so I can see the changes...
}

希望有人能帮忙,谢谢!

【问题讨论】:

    标签: c gtk refresh widget


    【解决方案1】:

    单线:

    gtk_container_foreach (GTK_CONTAINER (container), (void*) gtk_widget_destroy, NULL);
    

    【讨论】:

      【解决方案2】:

      这个对我有用(这是 unwind 答案的变体):

      Glib::ListHandle<Widget*> childList = this->get_children();
      Glib::ListHandle<Widget*>::iterator it = childList.begin();
      
      while (it != childList.end()) {
          remove(*(*it));
          it++;
      }
      

      (GTKMM 2.4)

      【讨论】:

      • 对于Gtk::manage()d 小部件有一个主要警告:Container.remove() 在这些小部件上不会 破坏小部件,假设它是一个典型的小部件,最初具有来自的浮动引用C库。相反,gtkmm 恢复浮动引用。因此,如果您 manage() 一个小部件并稍后将其从其父级中删除,它会通过浮动引用保持活动状态。这意味着,如果您希望像在 GTK+ 中那样删除 delete/free 小部件,那么您就错了,并可能导致大量内存泄漏。所以,你必须remove()delete,但既然deleteremove(),你应该只是delete
      【解决方案3】:

      这是我遵循的方法。因为我在 c++ 上使用 gtkmm

      Gtk::Box_Helpers::BoxList *childList = &vboxImgLst->children();
      Box_Helpers::BoxList::iterator start = childList->begin();
      Box_Helpers::BoxList::iterator end = childList->end();
      
      childList->erase(start, end);
      

      vboxImgLst在哪里,

      VBox *vboxImgLst;
      

      希望这对正在使用 gtkmm 和 c++ 的人有所帮助。

      谢谢

      【讨论】:

      • 谢天谢地,这个丑陋的附加 API 在 gtkmm 3 中被删除了,因为它看起来非常不直观,至少从 Container.get_children() 的 PoV 来看,它(必然)返回非拥有指针。
      【解决方案4】:

      删除所有子项:

      GList *children, *iter;
      
      children = gtk_container_get_children(GTK_CONTAINER(container));
      for(iter = children; iter != NULL; iter = g_list_next(iter))
        gtk_widget_destroy(GTK_WIDGET(iter->data));
      g_list_free(children);
      

      请注意,上面只是直接删除每个子小部件,而不是要求容器将其删除(使用gtk_container_remove()),这是recommended by the documentation 并且符合您的意图,所以我认为这很好。

      只要您实际将新构建的小部件添加并显示到容器中,“刷新视图”就没有任何意义。 GTK+ 是基于事件的,向容器中添加子元素可以使容器意识到它需要自动刷新其视觉外观。

      【讨论】:

      • 谢谢,我确定它需要刷新。
      • 你也可以这样做:gtk_container_foreach (GTK_CONTAINER (container), (GtkCallback) gtk_widget_destroy, NULL)
      猜你喜欢
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      相关资源
      最近更新 更多