gofyne

Capture key event within fyne.io table cell


The code below creates an (desktop) app with a table, the first cell has the focus. You can navigate in the table using the arrow keys.

I want to perform an action on a cell using the Enter key. To do this, I need to recognize the keystroke and get the coordinates (row and column) of the focused cell.

How do I do this?

package main

import (
    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/widget"
)

type Data struct {
    Field1 string
    Field2 string
}

var data = []Data{
    {"row 0 col 0", "row 0 col 1"},
    {"row 1 col 0", "row 1 col 1"},
}

func makeTableUI() (table *widget.Table) {
    table = widget.NewTable(
        func() (rows int, cols int) { // Size
            return len(data), 2
        },
        func() fyne.CanvasObject { // Create
            return widget.NewLabel("<template>")

        },
        func(id widget.TableCellID, o fyne.CanvasObject) { // Update
            switch id.Col {
            case 0:
                o.(*widget.Label).SetText(data[id.Row].Field1)
            case 1:
                o.(*widget.Label).SetText(data[id.Row].Field2)
            }
        },
    )

    return
}

func main() {
    a := app.New()
    w := a.NewWindow("Window")

    t := makeTableUI()
    w.SetContent(t)
    w.Canvas().Focus(t)

    w.Resize(fyne.NewSize(300, 300))
    w.CenterOnScreen()

    w.ShowAndRun()
}

I don't see from the documentation a way to intercept a key event from a table cell or the label in it, nor do I see a way to identify the focused cell in a key event on the canvas.


Solution

  • If you want a cell to handle input then use a Focusable widget (a custom one for you I guess? Or Entry as an example) this will be able to process keys and you don’t have to calculate row/col positions because the item itself will get the info.

    You might need to handle the table keys and feed them back out if you want it to behave both as getting its own events but also as being part of a table.

    (For example an Entry will want to handle arrow keys for cursor control, instead of moving table cell.)

    Alternatively, depending on your actual use-case you may just want to set the OnSelected callback for table which is designed to handle when user chooses a cell with mouse or keyboard.