本文作者:icy

go-Go Wails:用Go语言构建现代桌面应用

icy 今天 10 抢沙发
go-Go Wails:用Go语言构建现代桌面应用摘要: Go Wails:用Go语言构建现代桌面应用 什么是Wails? Wails是一个让开发者能够使用Go语言和Web技术(HTML/CSS/JavaScript)构建现代桌面应用程序...

go-Go Wails:用Go语言构建现代桌面应用

Go Wails:用Go语言构建现代桌面应用

什么是Wails?

Wails是一个让开发者能够使用Go语言和Web技术(HTML/CSS/JavaScript)构建现代桌面应用程序的框架。它允许你将Go的强大后端能力与灵活的前端技术相结合,创建出跨平台的桌面应用。

项目地址https://github.com/wailsapp/wails

核心特性

1. 跨平台支持

  • Windows
  • macOS
  • Linux

2. 技术栈

  • 后端:纯Go语言
  • 前端:任意Web技术(React、Vue、Angular、Svelte等)
  • 通信:自动生成的TypeScript绑定,实现前后端无缝通信

3. 现代化功能

  • 原生窗口装饰
  • 系统托盘支持
  • 菜单栏
  • 暗黑模式
  • 原生对话框
  • 文件系统访问

快速开始

安装Wails CLI

text
# 安装wails
go install github.com/wailsapp/wails/v2/cmd/wails@latest

# 验证安装
wails version

创建第一个Wails应用

text
# 创建新项目
wails init -n MyFirstApp -t react

# 进入项目目录
cd MyFirstApp

# 安装依赖
npm install

# 开发模式运行
wails dev

实例演示:待办事项应用

项目结构

text
todo-app/
├── main.go          # Go后端入口
├── frontend/        # 前端代码
│   ├── src/
│   │   ├── App.jsx
│   │   └── main.jsx
│   └── package.json
└── wails.json       # 项目配置

后端代码 (main.go)

text
package main

import (
	"context"
	"fmt"
	
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

// TodoItem 结构体
type TodoItem struct {
	ID        int    `json:"id"`
	Title     string `json:"title"`
	Completed bool   `json:"completed"`
}

// App 结构体
type App struct {
	ctx     context.Context
	todos   []TodoItem
	nextID  int
}

// NewApp 创建新应用实例
func NewApp() *App {
	return &App{
		todos:  []TodoItem{},
		nextID: 1,
	}
}

// Startup 应用启动时调用
func (a *App) Startup(ctx context.Context) {
	a.ctx = ctx
}

// AddTodo 添加待办事项
func (a *App) AddTodo(title string) TodoItem {
	todo := TodoItem{
		ID:        a.nextID,
		Title:     title,
		Completed: false,
	}
	a.todos = append(a.todos, todo)
	a.nextID++
	
	// 发送事件到前端
	runtime.EventsEmit(a.ctx, "todo-added", todo)
	
	return todo
}

// GetTodos 获取所有待办事项
func (a *App) GetTodos() []TodoItem {
	return a.todos
}

// ToggleTodo 切换待办事项状态
func (a *App) ToggleTodo(id int) {
	for i, todo := range a.todos {
		if todo.ID == id {
			a.todos[i].Completed = !a.todos[i].Completed
			runtime.EventsEmit(a.ctx, "todo-updated", a.todos[i])
			break
		}
	}
}

// DeleteTodo 删除待办事项
func (a *App) DeleteTodo(id int) {
	for i, todo := range a.todos {
		if todo.ID == id {
			a.todos = append(a.todos[:i], a.todos[i+1:]...)
			runtime.EventsEmit(a.ctx, "todo-deleted", id)
			break
		}
	}
}

// Greet 示例方法
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, from Go!", name)
}

前端代码 (App.jsx)

text
import React, { useState, useEffect } from 'react';
import './App.css';

function App() {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');

  // 从Go后端获取数据
  const loadTodos = async () => {
    const todos = await window.go.main.App.GetTodos();
    setTodos(todos);
  };

  // 添加待办事项
  const handleAddTodo = async () => {
    if (newTodo.trim()) {
      await window.go.main.App.AddTodo(newTodo);
      setNewTodo('');
      loadTodos();
    }
  };

  // 切换完成状态
  const handleToggleTodo = async (id) => {
    await window.go.main.App.ToggleTodo(id);
    loadTodos();
  };

  // 删除待办事项
  const handleDeleteTodo = async (id) => {
    await window.go.main.App.DeleteTodo(id);
    loadTodos();
  };

  // 监听Go后端事件
  useEffect(() => {
    const unsubscribe = window.runtime.EventsOn('todo-updated', () => {
      loadTodos();
    });

    return () => {
      unsubscribe();
    };
  }, []);

  // 初始加载
  useEffect(() => {
    loadTodos();
  }, []);

  return (
    <div className="app">
      <h1>待办事项应用</h1>
      
      <div className="add-todo">
        <input
          type="text"
          value={newTodo}
          onChange={(e) => setNewTodo(e.target.value)}
          placeholder="输入待办事项..."
          onKeyPress={(e) => e.key === 'Enter' && handleAddTodo()}
        />
        <button onClick={handleAddTodo}>添加</button>
      </div>

      <div className="todo-list">
        {todos.map(todo => (
          <div key={todo.id} className="todo-item">
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => handleToggleTodo(todo.id)}
            />
            <span className={todo.completed ? 'completed' : ''}>
              {todo.title}
            </span>
            <button 
              className="delete-btn"
              onClick={() => handleDeleteTodo(todo.id)}
            >
              删除
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

构建和打包

text
# 开发模式
wails dev

# 构建应用
wails build

# 平台特定构建
wails build -platform windows
wails build -platform darwin
wails build -platform linux

高级功能示例

1. 系统托盘

text
func (a *App) SetupTray() {
    menu := []*menu.MenuItem{
        menu.Text("显示应用", nil, func(_ *menu.CallbackData) {
            runtime.Show(a.ctx)
        }),
        menu.Separator(),
        menu.Text("退出", nil, func(_ *menu.CallbackData) {
            runtime.Quit(a.ctx)
        }),
    }
    
    runtime.NewTrayMenu(a.ctx, menu)
}

2. 原生对话框

text
func (a *App) OpenFileDialog() string {
    file, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
        Title: "选择文件",
        Filters: []runtime.FileFilter{
            {
                DisplayName: "文本文件",
                Pattern:     "*.txt;*.md",
            },
        },
    })
    
    if err != nil {
        return ""
    }
    return file
}

3. 数据库集成

text
import "github.com/jmoiron/sqlx"
import _ "github.com/mattn/go-sqlite3"

type Database struct {
    db *sqlx.DB
}

func (d *Database) Init() error {
    db, err := sqlx.Open("sqlite3", "data.db")
    if err != nil {
        return err
    }
    d.db = db
    return d.createTables()
}

优势与适用场景

优势

  1. 性能优异:Go编译为原生代码,执行效率高
  2. 内存安全:Go的内存管理机制避免常见的内存错误
  3. 并发强大:Go的goroutine模型适合处理并发任务
  4. 部署简单:单个可执行文件,无需运行时环境
  5. 现代化UI:可使用最新的Web技术构建界面

适用场景

  • 需要系统级访问的工具应用
  • 数据密集型桌面应用
  • 跨平台的企业工具
  • 原型开发和MVP验证
  • 需要离线功能的桌面应用

学习资源

  1. 官方文档https://wails.io/docs/
  2. 示例项目https://github.com/wailsapp/wails/tree/master/examples
  3. 社区模板:多种预配置模板可供选择
  4. Discord社区:活跃的开发者社区

总结

Wails为Go开发者提供了一个强大的桌面应用开发框架,结合了Go的性能优势和Web技术的灵活性。无论是构建简单的工具应用还是复杂的企业级桌面软件,Wails都能提供完整的解决方案。通过简单的API和现代化的开发体验,它大大降低了桌面应用开发的门槛。

如果你已经熟悉Go语言,并希望将你的技能扩展到桌面应用开发,Wails绝对值得尝试!

wails_20260204162122.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://zelig.cn/2026/03/357.html发布于 今天
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

验证码

评论列表 (暂无评论,10人围观)参与讨论

还没有评论,来说两句吧...