Set custom width for widgets

Viewed 311

This is my first attempt at building an application that does not use web technologies like CSS and JS. So I guess I don't have much idea about how Layouts, widgets fit together.

I have been trying to build a simple form but the result is not as expected.

Right now the result looks like this:

enter image description here

I want those 2 entry widgets in each row to consume the remaining space but it does not work.

Currently, my code for this looks like this:

checks := container.NewVBox(c1, c2)
names := container.NewVBox(n1, n2)
values := container.NewVBox(v1, v2)
win := container.NewHBox(checks, names, values)

I tried combinations of various layouts like Box, Border, Grid etc. but nothing worked. The grid layout worked but divides the columns in equal space so the checkboxes occupies 1/3 of the space too.

I need suggestions about which layout I can use so that checkboxes can take same space as it is now, but the remaining input fields on each row should use 50% of the rest of the empty space.

1 Answers

We can use the semantic names from the fyne layout system, for english as a first language the names are clear but for others I hope this post helps.
For the semantics, for example VBoxLayout naming indicates layout that is a box that fills vertical or MaxLayout being a box that will grab the maximum available space lay out the contents using all the space allocated.

For the issue above one approach would be to create a top level container with a VBoxLayout then use a MaxLayout to grab the available horizontal space and possibly address the issue in the question, then we can use a LayoutWithColumns to add the constraints we want on that space,

  • create some widgets as in question
    c1 := canvas.NewText("Canvas Object 1", color.White)
    c2 := canvas.NewText("Canvas Object 2", color.White)
    n1 := canvas.NewText("Canvas Object 3", color.White)
    n2 := canvas.NewText("Canvas Object 4", color.White)
  • make a top level container with the VBoxLayout
    topLevelLayOutContent = container.New(layout.NewVBoxLayout(),
  • now add are lower level containers using the MaxLayout and LayoutWithColumns for the constraints
    topLevelLayOutContent = container.New(layout.NewVBoxLayout(),
        container.New(layout.NewMaxLayout(),
            container.New(layout.NewGridLayoutWithColumns(2), c1, c2)),
        container.New(layout.NewMaxLayout(),
            container.New(layout.NewGridLayoutWithColumns(2), n1, n2)),
    )

looks like

simple working example

import (
    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/canvas"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/layout"
    "fyne.io/fyne/v2/app"
    "image/color"
)

var topLevelLayOutContent *fyne.Container

func main() {
    a := app.New()
    win := a.NewWindow("Server Mon")
    c1 := canvas.NewText("Canvas Object 1", color.White)
    c2 := canvas.NewText("Canvas Object 2", color.White)
    n1 := canvas.NewText("Canvas Object 3", color.White)
    n2 := canvas.NewText("Canvas Object 4", color.White)

    topLevelLayOutContent = container.New(layout.NewVBoxLayout(),
        container.New(layout.NewMaxLayout(),
            container.New(layout.NewGridLayoutWithColumns(2), c1, c2)),
        container.New(layout.NewMaxLayout(),
            container.New(layout.NewGridLayoutWithColumns(2), n1, n2)),
    )

    win.SetContent(topLevelLayOutContent)
    win.Resize(fyne.NewSize(float32(400), float32(30)))
    win.ShowAndRun()

}
  • answer updated to reflect comment below re MaxLayout behaviour
Related