diamondburned/gotk4

Emptying Listbox: ListBox.Remove() yells "Warning: Gtk: Tried to remove non-child" on removing its children

BigB84 opened this issue · 2 comments

Hi,
I'm in the middle of porting my golang app from GTK3 to GTK4.

I use ListBox to display ListBoxRows

Sometimes I need to remove all its children and fill it again with new.
Lets assume that there might be 500 of them in total.

import (
     "fmt"
     "github.com/diamondburned/gotk4/pkg/gtk/v4"
)

// (...) all stuff needed to run app
MyListBox := gtk.NewListBox()

// (...) part where I create Many ListBoxRows and pass them to MyListBox calling MyListBox.append(MyListBoxRow)
// So here there is MyListBox with 500 children
// I need to empty it so i do:

i := 500
for child := MyListBox.LastChild(); i >= 0; i-- {
	if child != nil {
		MyListBox.Remove(child)
		fmt.Println("child removed")
		}
}
fmt.Println("done removing")

But it yells:

(...)
3
2022/05/05 22:49:19 Warning: Gtk: Tried to remove non-child 0x64fbc50
child removed
2
2022/05/05 22:49:19 Warning: Gtk: Tried to remove non-child 0x64fbc50
child removed
1
2022/05/05 22:49:19 Warning: Gtk: Tried to remove non-child 0x64fbc50
child removed
0

does it mean that it passes condition that child is not nil but doesn't remove it?

To compare, If I want to do it in gotk3, I do:

import (
    "github.com/gotk3/gotk3/gtk"
)

// ...

	lst := MyListBox.GetChildren()
	lst.Foreach(func(i interface{}) {
		MyListBox.Remove(i.(gtk.IWidget))
	})

I did it that way because there's no .GetChildren() in gotk4. I even tried with selecting all child to workaround this but it didn't work.

I searched your examples repo and stack issues for some help but nothing really important:
https://stackoverflow.com/questions/36215425/vala-how-do-you-delete-all-the-children-of-a-gtk-container

But there's also .GetChildren()

Could you help me find solution for emptying ListBox?

Thanks for you work! :)

So I tried gotkit gtkutil .EachChild method.
It is great when you want to modify child but not if you want to remove it as order changes and gtk.BaseWidget(w).NextSibling() will return nil

If you try, only the first child gets removed.

However, this inspired me to write a proper loop:

// (...)
for child := MyListBox.FirstChild(); child != nil ; {
		MyListBox.Remove(child)
		child = MyListBox.FirstChild()
}

This solves the problem!
Thanks :)