从Gtk.FlowBox中删除小部件

从Gtk.FlowBox中删除小部件,gtk,vala,Gtk,Vala,我试图通过销毁一个小部件从Gtk.FlowBox中删除一个小部件,但是有一个灰色的框留在原地。你知道我如何移除灰色框,以便在移除小部件后相邻的小部件就位吗 以下是小部件的打包方式: 1-将两个图像(来自pixbuf)和标签添加到覆盖图像中 2-将覆盖图像添加到事件框 3-将EventBox添加到流框中 我尝试过以下方法: 1-销毁EventBox 2-获取并销毁覆盖图像的所有子项,然后销毁覆盖图像和EventBox 在这两种情况下,小部件都会被删除,但一个空白区域会保留在其位置上,单击该区域时为

我试图通过销毁一个小部件从Gtk.FlowBox中删除一个小部件,但是有一个灰色的框留在原地。你知道我如何移除灰色框,以便在移除小部件后相邻的小部件就位吗

以下是小部件的打包方式: 1-将两个图像(来自pixbuf)和标签添加到覆盖图像中 2-将覆盖图像添加到事件框 3-将EventBox添加到流框中

我尝试过以下方法: 1-销毁EventBox 2-获取并销毁覆盖图像的所有子项,然后销毁覆盖图像和EventBox

在这两种情况下,小部件都会被删除,但一个空白区域会保留在其位置上,单击该区域时为灰色,但不会执行任何操作-请参见图片

如何删除这个空白,以便下一个小部件自动落在小部件被删除的位置,下一个小部件落在它的位置,依此类推

代码在这里可用,“removeSelectedBooksFromLibrary”是从流框中删除用户选择的EventBox的方法

这是从FlowBox添加小部件的代码

这是从流框中删除小部件的代码

提前谢谢

下面是一个添加了解决方案的工作示例,它删除了小部件及其父部件

public class FlowBoxIssue : Gtk.Window {

  public static int main (string[] args) {
      Gtk.init (ref args);
      FlowBoxIssue window = new FlowBoxIssue();
      window.show_all ();
      Gtk.main ();
      return 0;
  }

  public FlowBoxIssue () {
      this.title = "FlowBox Issue";
      this.window_position = Gtk.WindowPosition.CENTER;
      this.destroy.connect (Gtk.main_quit);
      this.set_default_size (800, 600);

      Gtk.FlowBox library_flowbox = new Gtk.FlowBox();
      Gtk.Box library_mainbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 20);

      Gtk.ScrolledWindow library_scroll = new Gtk.ScrolledWindow (null, null);
            library_scroll.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
            library_scroll.add (library_flowbox);

      Gtk.Overlay aOverlayImage1 = new Gtk.Overlay();
      Gtk.EventBox aEventBox1 = new Gtk.EventBox();
      Gtk.EventBox aEventBox2 = new Gtk.EventBox();
      Gtk.EventBox aEventBox3 = new Gtk.EventBox();
      try{
        Gdk.Pixbuf aBookCover1 = new Gdk.Pixbuf.from_file_at_scale("cover.png", 200, 250, false);
        Gtk.Image aCoverImage1 = new Gtk.Image.from_pixbuf(aBookCover1);

        aOverlayImage1.add(aCoverImage1);
        Gtk.Label overlayTextLabel1 = new Gtk.Label("Label 1");
        aOverlayImage1.add_overlay(overlayTextLabel1);
        aEventBox1.add(aOverlayImage1);
        library_flowbox.add (aEventBox1);
      }catch(Error e){

      }

      Gtk.Overlay aOverlayImage2 = new Gtk.Overlay();
      try{
        Gdk.Pixbuf aBookCover2 = new Gdk.Pixbuf.from_file_at_scale("cover.png", 200, 250, false);
        Gtk.Image aCoverImage2 = new Gtk.Image.from_pixbuf(aBookCover2);

        aOverlayImage2.add(aCoverImage2);
        Gtk.Label overlayTextLabel2 = new Gtk.Label("Label 2");
        aOverlayImage2.add_overlay(overlayTextLabel2);
        aEventBox2.add(aOverlayImage2);
        library_flowbox.add (aEventBox2);
      }catch(Error e){

      }

      Gtk.Overlay aOverlayImage3 = new Gtk.Overlay();
      try{
        Gdk.Pixbuf aBookCover3 = new Gdk.Pixbuf.from_file_at_scale("cover.png", 200, 250, false);
        Gtk.Image aCoverImage3 = new Gtk.Image.from_pixbuf(aBookCover3);

        aOverlayImage3.add(aCoverImage3);
        Gtk.Label overlayTextLabel3 = new Gtk.Label("Label 3");
        aOverlayImage3.add_overlay(overlayTextLabel3);
        aEventBox3.add(aOverlayImage3);
        library_flowbox.add (aEventBox3);
      }catch(Error e){

      }

      Gtk.Button delete_button = new Gtk.Button.with_label("Delete Pix");
      delete_button.clicked.connect (() => {
          //This is the line which resolved the issue - get the parent of the widget and destroy it and then destroy the widget
          aEventBox2.get_parent().destroy();
                aEventBox2.destroy();
          });

      library_mainbox.pack_start(library_scroll, true, true, 0);
      library_mainbox.pack_end(delete_button, true, false, 0);
      this.add(library_mainbox);
  }

}

每次向
GtkFlowBox
添加子窗口小部件时,流框窗口小部件将在两者之间添加一个隐式子窗口小部件,用于事件处理和样式设置目的-作为以下状态的文档:

尽管GtkFlowBox必须只有GtkFlowBoxChild子项,但您可以通过gtk_container_add()向其添加任何类型的小部件,并且GtkFlowBoxChild小部件将自动插入到框和小部件之间

这意味着该行:

library_grid.add(aEventBox);
实际上相当于:

var flowbox_child = new Gtk.FlowBoxChild();
flowbox_child.add(aEventBox);
library_grid.add(flowbox_child);
如果要从
GtkFlowBox
中删除小部件,并且只保留对所添加子部件的引用,则需要检索其父部件并从
GtkFlowBox
中删除该小部件:

aEventBox.get_parent().destroy();
// or
library_grid.remove(aEventBox.get_parent());

你忘了链接代码(这应该是问题本身的一部分)。为忘记提及代码而道歉。我将尝试创建一个MCVE并更新问题。非常感谢您的快速解释性回答。该解决方案在我的主代码和我正在创建的MVCE中都起作用。我已经在问题中添加了MVCE,以防它帮助有相同问题的人。遗憾的是我没有正确阅读文档。再次感谢!