File dialogs
Open, save, and folder selection.
Este conteúdo não está disponível em sua língua ainda.
Wails provides native message dialogs with platform-appropriate appearance: info, warning, error, and question dialogs with customisable titles, messages, and buttons. Simple API, native behaviour, accessible by default.
Message dialogs are accessed through the app.Dialog manager:
app.Dialog.Info()app.Dialog.Question()app.Dialog.Warning()app.Dialog.Error()All methods return a *MessageDialog that can be configured using method chaining.
Display informational messages:
app.Dialog.Info(). SetTitle("Success"). SetMessage("File saved successfully!"). Show()Use cases:
Example - Save confirmation:
func saveFile(app *application.App, path string, data []byte) error { if err := os.WriteFile(path, data, 0644); err != nil { return err }
app.Dialog.Info(). SetTitle("File Saved"). SetMessage(fmt.Sprintf("Saved to %s", filepath.Base(path))). Show()
return nil}Show warnings:
app.Dialog.Warning(). SetTitle("Warning"). SetMessage("This action cannot be undone."). Show()Use cases:
Example - Disk space warning:
func checkDiskSpace(app *application.App) { available := getDiskSpace()
if available < 100*1024*1024 { // Less than 100MB app.Dialog.Warning(). SetTitle("Low Disk Space"). SetMessage(fmt.Sprintf("Only %d MB available.", available/(1024*1024))). Show() }}Display errors:
app.Dialog.Error(). SetTitle("Error"). SetMessage("Failed to connect to server."). Show()Use cases:
Example - Network error:
func fetchData(app *application.App, url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { app.Dialog.Error(). SetTitle("Network Error"). SetMessage(fmt.Sprintf("Failed to connect: %v", err)). Show() return nil, err } defer resp.Body.Close()
return io.ReadAll(resp.Body)}Ask users questions and handle responses via button callbacks:
dialog := app.Dialog.Question(). SetTitle("Confirm"). SetMessage("Save changes before closing?")
save := dialog.AddButton("Save")save.OnClick(func() { saveChanges()})
dontSave := dialog.AddButton("Don't Save")dontSave.OnClick(func() { // Continue without saving})
cancel := dialog.AddButton("Cancel")cancel.OnClick(func() { // Don't close})
dialog.SetDefaultButton(save)dialog.SetCancelButton(cancel)dialog.Show()Use cases:
Example - Unsaved changes:
func closeDocument(app *application.App) { if !hasUnsavedChanges() { doClose() return }
dialog := app.Dialog.Question(). SetTitle("Unsaved Changes"). SetMessage("Do you want to save your changes?")
save := dialog.AddButton("Save") save.OnClick(func() { if saveDocument() { doClose() } })
dontSave := dialog.AddButton("Don't Save") dontSave.OnClick(func() { doClose() })
cancel := dialog.AddButton("Cancel") // Cancel button has no callback - just closes the dialog
dialog.SetDefaultButton(save) dialog.SetCancelButton(cancel) dialog.Show()}dialog := app.Dialog.Info(). SetTitle("Operation Complete"). SetMessage("All files have been processed successfully.")Best practices:
Single button (Info/Warning/Error):
Info, warning, and error dialogs display a default “OK” button:
app.Dialog.Info(). SetMessage("Done!"). Show()You can also add custom buttons:
dialog := app.Dialog.Info(). SetMessage("Done!")ok := dialog.AddButton("Got it!")dialog.SetDefaultButton(ok)dialog.Show()Multiple buttons (Question):
Use AddButton() to add buttons, which returns a *Button you can configure:
dialog := app.Dialog.Question(). SetMessage("Choose an action")
option1 := dialog.AddButton("Option 1")option1.OnClick(func() { handleOption1()})
option2 := dialog.AddButton("Option 2")option2.OnClick(func() { handleOption2()})
option3 := dialog.AddButton("Option 3")option3.OnClick(func() { handleOption3()})
dialog.Show()Default and Cancel buttons:
Use SetDefaultButton() to specify which button is highlighted and triggered by Enter.
Use SetCancelButton() to specify which button is triggered by Escape.
dialog := app.Dialog.Question(). SetMessage("Delete file?")
deleteBtn := dialog.AddButton("Delete")deleteBtn.OnClick(func() { performDelete()})
cancelBtn := dialog.AddButton("Cancel")// No callback needed - just dismisses dialog
dialog.SetDefaultButton(cancelBtn) // Safe option as defaultdialog.SetCancelButton(cancelBtn) // Escape triggers Canceldialog.Show()You can also use the fluent SetAsDefault() and SetAsCancel() methods on buttons:
dialog := app.Dialog.Question(). SetMessage("Delete file?")
dialog.AddButton("Delete").OnClick(func() { performDelete()})
dialog.AddButton("Cancel").SetAsDefault().SetAsCancel()
dialog.Show()Best practices:
Set a custom icon for the dialog:
app.Dialog.Info(). SetTitle("Custom Icon Example"). SetMessage("Using a custom icon"). SetIcon(myIconBytes). Show()Attach to specific window:
dialog := app.Dialog.Question(). SetMessage("Window-specific question"). AttachToWindow(window)
dialog.AddButton("OK")dialog.Show()Benefits:
func deleteFiles(app *application.App, paths []string) { // Confirm deletion message := fmt.Sprintf("Delete %d file(s)?", len(paths)) if len(paths) == 1 { message = fmt.Sprintf("Delete %s?", filepath.Base(paths[0])) }
dialog := app.Dialog.Question(). SetTitle("Confirm Delete"). SetMessage(message)
deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { // Perform deletion var errs []error for _, path := range paths { if err := os.Remove(path); err != nil { errs = append(errs, err) } }
// Show result if len(errs) > 0 { app.Dialog.Error(). SetTitle("Delete Failed"). SetMessage(fmt.Sprintf("Failed to delete %d file(s)", len(errs))). Show() } else { app.Dialog.Info(). SetTitle("Delete Complete"). SetMessage(fmt.Sprintf("Deleted %d file(s)", len(paths))). Show() } })
cancelBtn := dialog.AddButton("Cancel") dialog.SetDefaultButton(cancelBtn) dialog.SetCancelButton(cancelBtn) dialog.Show()}func confirmQuit(app *application.App) { dialog := app.Dialog.Question(). SetTitle("Quit"). SetMessage("You have unsaved work. Are you sure you want to quit?")
yes := dialog.AddButton("Yes") yes.OnClick(func() { app.Quit() })
no := dialog.AddButton("No") dialog.SetDefaultButton(no) dialog.Show()}func showUpdateDialog(app *application.App) { dialog := app.Dialog.Question(). SetTitle("Update"). SetMessage("A new version is available. The cancel button is selected when pressing escape.")
download := dialog.AddButton("📥 Download") download.OnClick(func() { app.Dialog.Info().SetMessage("Downloading...").Show() })
cancel := dialog.AddButton("Cancel")
dialog.SetDefaultButton(download) dialog.SetCancelButton(cancel) dialog.Show()}func showCustomIconQuestion(app *application.App, iconBytes []byte) { dialog := app.Dialog.Question(). SetTitle("Custom Icon Example"). SetMessage("Using a custom icon"). SetIcon(iconBytes)
likeIt := dialog.AddButton("I like it!") likeIt.OnClick(func() { app.Dialog.Info().SetMessage("Thanks!").Show() })
notKeen := dialog.AddButton("Not so keen...") notKeen.OnClick(func() { app.Dialog.Info().SetMessage("Too bad!").Show() })
dialog.SetDefaultButton(likeIt) dialog.Show()}File dialogs
Open, save, and folder selection.
Custom dialogs
Create custom dialog windows.
Notifications
Non-intrusive notifications.
Events
Use events for non-blocking communication.
Questions? Ask in Discord or check the dialog examples.