Table
This is a table widget in Fyne used to display data in rows and columns.
Basic Table
Section titled “Basic Table”Show Code
package main
import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget")
func main() { myApp := app.New() w := myApp.NewWindow("Table with Headers")
// Sample data headers := []string{"Category", "Item", "Quantity"} data := [][]string{ {"Fruits", "Apples", "10"}, {"Fruits", "Bananas", "25"}, {"Vegetables", "Carrots", "12"}, {"Vegetables", "Spinach", "7"}, {"Grains", "Rice", "50"}, }
// Table has headers + data (rows+1) table := widget.NewTable( func() (int, int) { return len(data) + 1, len(headers) // +1 for header row }, func() fyne.CanvasObject { return widget.NewLabel("placeholder") }, func(id widget.TableCellID, cell fyne.CanvasObject) { label := cell.(*widget.Label) if id.Row == 0 { // Header row label.SetText(headers[id.Col]) label.TextStyle = fyne.TextStyle{Bold: true} } else { // Data rows label.SetText(data[id.Row-1][id.Col]) label.TextStyle = fyne.TextStyle{} } }, )
table.SetColumnWidth(0, 100) table.SetColumnWidth(1, 120) table.SetColumnWidth(2, 80)
content := container.NewStack(table)
w.SetContent(content) w.Resize(fyne.NewSize(350, 250)) w.ShowAndRun()}Complete CRUD
Section titled “Complete CRUD”This Demostrates the power of tables by creating a complete CRUD APP. The app allows people Add, Delete and Update items in real-time.
Show Code
package main
import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/widget")
type Item struct { Name string Category string Quantity string}
func main() { myApp := app.New() w := myApp.NewWindow("CRUD Table")
// Initial data data := []Item{ {"Apples", "Fruit", "10"}, {"Bananas", "Fruit", "20"}, {"Carrots", "Vegetable", "15"}, }
// Table reference for refreshing it var table *widget.Table
// Refresh function refreshTable := func() { table.Refresh() }
// Define table table = widget.NewTable( func() (int, int) { return len(data) + 1, 4 // +1 for headers }, func() fyne.CanvasObject { // Each cell is wrapped in padding so we can add spacing return container.NewPadded(widget.NewLabel("")) }, func(id widget.TableCellID, obj fyne.CanvasObject) { cell := obj.(*fyne.Container) cell.Objects = nil // reset container
if id.Row == 0 { // header row headers := []string{"Name", "Category", "Quantity", "Actions"} lbl := widget.NewLabel(headers[id.Col]) lbl.TextStyle = fyne.TextStyle{Bold: true} cell.Add(lbl) } else { row := id.Row - 1 switch id.Col { case 0: cell.Add(widget.NewLabel(data[row].Name)) case 1: cell.Add(widget.NewLabel(data[row].Category)) case 2: cell.Add(widget.NewLabel(data[row].Quantity)) case 3: editBtn := widget.NewButton("Edit", func() { showEditDialog(w, &data[row], refreshTable) }) deleteBtn := widget.NewButton("Delete", func() { data = append(data[:row], data[row+1:]...) refreshTable() }) // Add spacing between buttons cell.Add(container.NewHBox( editBtn, widget.NewLabel(" "), deleteBtn, )) } } }, )
table.SetColumnWidth(0, 100) table.SetColumnWidth(1, 120) table.SetColumnWidth(2, 80)
// Add new item button addBtn := widget.NewButton("Add Item", func() { showAddDialog(w, &data, refreshTable) })
content := container.NewBorder(addBtn, nil, nil, nil, table) w.SetContent(content) w.Resize(fyne.NewSize(600, 400)) w.ShowAndRun()}
// a function to add itemsfunc showAddDialog(win fyne.Window, data *[]Item, refresh func()) { nameEntry := widget.NewEntry() categoryEntry := widget.NewEntry() quantityEntry := widget.NewEntry()
form := &widget.Form{ Items: []*widget.FormItem{ {Text: "Name", Widget: nameEntry}, {Text: "Category", Widget: categoryEntry}, {Text: "Quantity", Widget: quantityEntry}, }, OnSubmit: func() { *data = append(*data, Item{ Name: nameEntry.Text, Category: categoryEntry.Text, Quantity: quantityEntry.Text, }) refresh() win.Canvas().Overlays().Top().Hide() }, }
d := dialog.NewCustom("Add Item", "Close", form, win) d.Resize(fyne.NewSize(400, 250)) d.Show()}
// a function to edit itemsfunc showEditDialog(win fyne.Window, item *Item, refresh func()) { nameEntry := widget.NewEntry() nameEntry.SetText(item.Name)
categoryEntry := widget.NewEntry() categoryEntry.SetText(item.Category)
quantityEntry := widget.NewEntry() quantityEntry.SetText(item.Quantity)
form := &widget.Form{ Items: []*widget.FormItem{ {Text: "Name", Widget: nameEntry}, {Text: "Category", Widget: categoryEntry}, {Text: "Quantity", Widget: quantityEntry}, }, OnSubmit: func() { item.Name = nameEntry.Text item.Category = categoryEntry.Text item.Quantity = quantityEntry.Text refresh() win.Canvas().Overlays().Top().Hide() }, }
d := dialog.NewCustom("Edit Item", "Close", form, win) d.Resize(fyne.NewSize(400, 250)) d.Show()}