Search code examples
govariadic-functionsfyne

fyne create rows in a container from a slice of containers


I need to have a slice called rows containing a number of fyne.Container structs. Then I need to show them all as rows in a window.

I tried doing this:

rows := []*fyne.Container{}
rows = append(
    rows, 
    container.New(
        layout.NewGridLayout(4),
        widget.NewLabel("Trigger"),
        widget.NewLabel("Text"),
        widget.NewLabel("Enter"),
        widget.NewLabel("Active"),
    ),
)

w.SetContent(
    container.New(
        layout.NewGridLayout(1),
        rows...
    ),
)

but I get

cannot use rows (type []*fyne.Container) as type []fyne.CanvasObject in argument to container.New

And I don't understand why if I do this:

w.SetContent(
    container.New(
        layout.NewGridLayout(1),
        container.New(
            layout.NewGridLayout(4),
            widget.NewLabel("Trigger"),
            widget.NewLabel("Text"),
            widget.NewLabel("Enter"),
            widget.NewLabel("Active"),
        ),
        container.New(
            layout.NewGridLayout(4),
            widget.NewLabel("Trigger"),
            widget.NewLabel("Text"),
            widget.NewLabel("Enter"),
            widget.NewLabel("Active"),
        ),
    ),
)

It works fine... Shouldn't it be the same passing individual structs or a []type...?

Thanks!


Solution

  • The method expects a slice of fyne.CanvasObjects, which is an interface that the struct fyne.Container implements.

    A slice of a struct type cannot be used in place of a slice of an interface type, even if the struct type satisfies the interface.

    Your slice should be of the interface type not the struct type. You can then append objects that fulfill the interface to that slice:

    rows := []fyne.CanvasObject{}
    rows = append(
        rows, 
        container.New(
            layout.NewGridLayout(4),
            widget.NewLabel("Trigger"),
            widget.NewLabel("Text"),
            widget.NewLabel("Enter"),
            widget.NewLabel("Active"),
        ),
    )