Search code examples
gofyne

Using Fyne to bind a list widget to a slice of structs


I have a collection of data items and am trying to use Fyne to put together a GUI to edit the collection. I've figured out how to use binding to display the collection, but I can't figure out how to then be able to edit the items.

Here's a slightly simplified version of what I have:

type Item struct {
  Name string
  Slot1 bool
  Slot2 bool
}

type ItemList struct {
  Items []Item
}

I won't show them, but I've added the methods to these two types so that the former implements binding.DataItem and the latter implements binding.DataList.

Now for the display:

var dataList := ItemList{
 ...
 ...
}

list := NewListWithData(
        dataList,
        func() fyne.CanvasObject {
           label := widget.NewLabel("placeholder")
           c1 := widget.NewCheck("", func(bool) {})
           c2 := widget.NewCheck("", func(bool) {})
           return container.NewHBox(label, c1, c2)
        },
        func(di binding.DatItem, obj fyne.CanvasObject) {
           ct := obj.(*fyne.Container)
           label := ct.Objects[0].(*widget.Label)
           c1 := ct.Objects[1].(*widget.Check)
           c2 := ct.Objects[2].(*widget.Check)
           item := di.(Item)
           label.SetText(item.Name)
           c1.SetChecked(item.Slot1)
           c2.SetChecked(item.Slot2)
        },
}

I suspect that at this point I need to do something like values := binding.BindStruct(&item), but if I do so, I'm not sure how to then get those into the label and check widgets.


Solution

  • You need to wire up the input controls to the binding (the item for the struct is passed in through di). If you already have the methods in Item that gain you access to the child items bound then you're most of the way there.

    To wire up the edit capabilities replace label.SetText(...) with label.Bind(...) and c1.SetChecked(...) with c1.Bind(...). This will both set the current values an