Skip to content

App Shortcuts

Add global and window-specific keyboard shortcuts to your Fyne applications for faster navigation and improved user experience.

Show Code
package main
import (
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("App Shortcuts")
label := widget.NewLabel("Press Ctrl+N or Ctrl+Q")
// Shortcut: Ctrl+N (New)
newShortcut := &desktop.CustomShortcut{
KeyName: fyne.KeyN,
Modifier: fyne.KeyModifierControl,
}
// Shortcut: Ctrl+Q (Quit)
quitShortcut := &desktop.CustomShortcut{
KeyName: fyne.KeyQ,
Modifier: fyne.KeyModifierControl,
}
// Register shortcuts
w.Canvas().AddShortcut(newShortcut, func(shortcut fyne.Shortcut) {
label.SetText("Shortcut Triggered: New (Ctrl+N)")
fmt.Println("New action executed")
})
w.Canvas().AddShortcut(quitShortcut, func(shortcut fyne.Shortcut) {
label.SetText("Shortcut Triggered: Quit (Ctrl+Q)")
fmt.Println("Quitting app...")
a.Quit()
})
w.SetContent(container.NewCenter(label))
w.Resize(fyne.NewSize(400, 200))
w.ShowAndRun()
}
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/driver/desktop"
"fyne.io/fyne/v2/widget"
)
type Item struct {
Name string
Category string
Quantity string
}
var items []Item
var table *widget.Table
func main() {
a := app.New()
w := a.NewWindow("CRUD App with Shortcuts")
// Shortcuts with descriptions
items = []Item{
{"Apples", "Fruit", "10"},
{"Pens", "Stationery", "50"},
}
refresh := func() { table.Refresh() }
// Create table
table = widget.NewTable(
func() (int, int) { return len(items) + 1, 3 },
func() fyne.CanvasObject { return widget.NewLabel("") },
func(id widget.TableCellID, o fyne.CanvasObject) {
label := o.(*widget.Label)
if id.Row == 0 {
headers := []string{"Name", "Category", "Quantity"}
label.SetText(headers[id.Col])
label.TextStyle = fyne.TextStyle{Bold: true}
} else {
item := items[id.Row-1]
switch id.Col {
case 0:
label.SetText(item.Name)
case 1:
label.SetText(item.Category)
case 2:
label.SetText(item.Quantity)
}
}
},
)
// ✅ Set custom widths for each column
table.SetColumnWidth(0, 200) // Name column
table.SetColumnWidth(1, 150) // Category column
table.SetColumnWidth(2, 100) // Quantity column
// Shortcuts
// Ctrl+N → Add New Item
newShortcut := &desktop.CustomShortcut{KeyName: fyne.KeyN, Modifier: fyne.KeyModifierControl}
w.Canvas().AddShortcut(newShortcut, func(shortcut fyne.Shortcut) {
showAddDialog(w, refresh)
})
// Ctrl+E → Edit First Item (demo, can be expanded to selected item later)
editShortcut := &desktop.CustomShortcut{KeyName: fyne.KeyE, Modifier: fyne.KeyModifierControl}
w.Canvas().AddShortcut(editShortcut, func(shortcut fyne.Shortcut) {
if len(items) > 0 {
showEditDialog(w, &items[0], refresh)
} else {
dialog.ShowInformation("Edit", "No items available", w)
}
})
// Delete → Delete First Item (demo)
deleteShortcut := &desktop.CustomShortcut{KeyName: fyne.KeyDelete}
w.Canvas().AddShortcut(deleteShortcut, func(shortcut fyne.Shortcut) {
if len(items) > 0 {
items = items[1:]
refresh()
}
})
// Ctrl+Q → Quit
quitShortcut := &desktop.CustomShortcut{KeyName: fyne.KeyQ, Modifier: fyne.KeyModifierControl}
w.Canvas().AddShortcut(quitShortcut, func(shortcut fyne.Shortcut) {
a.Quit()
})
w.SetContent(container.NewBorder(nil, nil, nil, nil, table))
w.Resize(fyne.NewSize(600, 300))
w.ShowAndRun()
}
func showAddDialog(win fyne.Window, 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() {
items = append(items, Item{nameEntry.Text, categoryEntry.Text, quantityEntry.Text})
refresh()
win.Canvas().Overlays().Top().Hide()
},
}
dialog.ShowCustom("Add Item", "Close", form, win)
}
func 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()
},
}
dialog.ShowCustom("Edit Item", "Close", form, win)
}