赞
踩
fyne是一个用go编写的GUI框架,它上手简单,语法清晰,界面美观。
教程地址:
- https://pkg.go.dev/fyne.io/fyne/v2#section-readme
- https://www.topgoer.cn/docs/goday/goday-1crdp17nj4v6p
项目地址:https://gitee.com/Zifasdfa/ziyiMarkDown
首先需要有go的环境【我的本地环境是1.17】
- go环境搭建过程:https://editor.csdn.net/md/?articleId=130175889
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/storage" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" _ "io/ioutil" "os" "strings" ) /* 用fyne实现简易版typora */ func init() { //设置中文字体:解决中文乱码问题 fontPaths := findfont.List() for _, path := range fontPaths { if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } } type config struct { EditWidget *widget.Entry //编辑框 PreviewWidget *widget.RichText //预览框【富文本】 CurrentFile fyne.URI SaveMenuItem *fyne.MenuItem } var cfg config func main() { a := app.New() win := a.NewWindow("Markdown") edit, preview := cfg.makeUI() cfg.createMenuItems(win) //布局选择左右布局,一边是编辑,一边是预览 win.SetContent(container.NewHSplit(edit, preview)) win.Resize(fyne.Size{Width: 800, Height: 500}) win.CenterOnScreen() win.ShowAndRun() } //初始化界面 func (app *config) makeUI() (*widget.Entry, *widget.RichText) { edit := widget.NewMultiLineEntry() preview := widget.NewRichTextFromMarkdown("") app.EditWidget = edit app.PreviewWidget = preview edit.OnChanged = preview.ParseMarkdown return edit, preview } 添加过滤器,只能打开.md结尾文件 //var filter = storage.NewExtensionFileFilter([]string{".md", ".MD"}) // //创建主菜单 func (app *config) createMenuItems(win fyne.Window) { openMenuItem := fyne.NewMenuItem("open...", func() {}) saveMenuItem := fyne.NewMenuItem("Save...", func() {}) app.SaveMenuItem = saveMenuItem app.SaveMenuItem.Disabled = true saveAsMenuItem := fyne.NewMenuItem("Save as...", func() {}) fileMenu := fyne.NewMenu("File", openMenuItem, saveMenuItem, saveAsMenuItem) menu := fyne.NewMainMenu(fileMenu) win.SetMainMenu(menu) }
- 添加过滤器
- 实现另存为
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/storage" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" _ "io/ioutil" "os" "strings" ) /* 用fyne实现简易版typora */ func init() { //设置中文字体:解决中文乱码问题 fontPaths := findfont.List() for _, path := range fontPaths { if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } } type config struct { EditWidget *widget.Entry //编辑框 PreviewWidget *widget.RichText //预览框【富文本】 CurrentFile fyne.URI SaveMenuItem *fyne.MenuItem } var cfg config func main() { a := app.New() win := a.NewWindow("Markdown") edit, preview := cfg.makeUI() cfg.createMenuItems(win) //布局选择左右布局,一边是编辑,一边是预览 win.SetContent(container.NewHSplit(edit, preview)) win.Resize(fyne.Size{Width: 800, Height: 500}) win.CenterOnScreen() win.ShowAndRun() } //初始化界面 func (app *config) makeUI() (*widget.Entry, *widget.RichText) { edit := widget.NewMultiLineEntry() preview := widget.NewRichTextFromMarkdown("") app.EditWidget = edit app.PreviewWidget = preview edit.OnChanged = preview.ParseMarkdown return edit, preview } //添加过滤器,只能打开.md结尾文件 var filter = storage.NewExtensionFileFilter([]string{".md", ".MD"}) //创建主菜单 func (app *config) createMenuItems(win fyne.Window) { openMenuItem := fyne.NewMenuItem("open...", func() {}) //openMenuItem := fyne.NewMenuItem("open...", app.openFunc(win)) saveMenuItem := fyne.NewMenuItem("Save...", func() {}) //saveMenuItem := fyne.NewMenuItem("Save...", app.saveFunc(win)) app.SaveMenuItem = saveMenuItem app.SaveMenuItem.Disabled = true //另存为 saveAsMenuItem := fyne.NewMenuItem("Save as...", app.saveAsFunc(win)) fileMenu := fyne.NewMenu("File", openMenuItem, saveMenuItem, saveAsMenuItem) menu := fyne.NewMainMenu(fileMenu) win.SetMainMenu(menu) } //【另存为】功能实现 func (app *config) saveAsFunc(win fyne.Window) func() { return func() { saveDialog := dialog.NewFileSave(func(write fyne.URIWriteCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if write == nil { //user canceled return } if !strings.HasPrefix(strings.ToLower(write.URI().String()), ".md") { dialog.ShowInformation("Error", "Please name your file with a .md extension!", win) return } //save file write.Write([]byte(app.EditWidget.Text)) app.CurrentFile = write.URI() defer write.Close() win.SetTitle(win.Title() + "-" + write.URI().Name()) app.SaveMenuItem.Disabled = false }, win) saveDialog.SetFileName("untitled.md") saveDialog.SetFilter(filter) saveDialog.Show() } }
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/storage" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" "io/ioutil" "os" "strings" ) /* 用fyne实现简易版typora */ func init() { //设置中文字体:解决中文乱码问题 fontPaths := findfont.List() for _, path := range fontPaths { if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } } type config struct { EditWidget *widget.Entry //编辑框 PreviewWidget *widget.RichText //预览框【富文本】 CurrentFile fyne.URI SaveMenuItem *fyne.MenuItem } var cfg config func main() { a := app.New() win := a.NewWindow("Markdown") edit, preview := cfg.makeUI() cfg.createMenuItems(win) //布局选择左右布局,一边是编辑,一边是预览 win.SetContent(container.NewHSplit(edit, preview)) win.Resize(fyne.Size{Width: 800, Height: 500}) win.CenterOnScreen() win.ShowAndRun() } //初始化界面 func (app *config) makeUI() (*widget.Entry, *widget.RichText) { edit := widget.NewMultiLineEntry() preview := widget.NewRichTextFromMarkdown("") app.EditWidget = edit app.PreviewWidget = preview edit.OnChanged = preview.ParseMarkdown return edit, preview } //添加过滤器,只能打开.md结尾文件 var filter = storage.NewExtensionFileFilter([]string{".md", ".MD"}) //创建主菜单 func (app *config) createMenuItems(win fyne.Window) { //打开文件 openMenuItem := fyne.NewMenuItem("open...", app.openFunc(win)) saveMenuItem := fyne.NewMenuItem("Save...", func() {}) //saveMenuItem := fyne.NewMenuItem("Save...", app.saveFunc(win)) app.SaveMenuItem = saveMenuItem app.SaveMenuItem.Disabled = true //另存为 saveAsMenuItem := fyne.NewMenuItem("Save as...", app.saveAsFunc(win)) fileMenu := fyne.NewMenu("File", openMenuItem, saveMenuItem, saveAsMenuItem) menu := fyne.NewMainMenu(fileMenu) win.SetMainMenu(menu) } //【打开文件】功能 func (app *config) openFunc(win fyne.Window) func() { return func() { openDialog := dialog.NewFileOpen(func(read fyne.URIReadCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if read == nil { return } defer read.Close() data, err := ioutil.ReadAll(read) if err != nil { dialog.ShowError(err, win) return } app.EditWidget.SetText(string(data)) app.CurrentFile = read.URI() win.SetTitle(win.Title() + "-" + read.URI().Name()) app.SaveMenuItem.Disabled = false }, win) //添加.md过滤器 openDialog.SetFilter(filter) openDialog.Show() } } //【另存为】功能实现 func (app *config) saveAsFunc(win fyne.Window) func() { return func() { saveDialog := dialog.NewFileSave(func(write fyne.URIWriteCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if write == nil { //user canceled return } if !strings.HasPrefix(strings.ToLower(write.URI().String()), ".md") { dialog.ShowInformation("Error", "Please name your file with a .md extension!", win) return } //save file write.Write([]byte(app.EditWidget.Text)) app.CurrentFile = write.URI() defer write.Close() win.SetTitle(win.Title() + "-" + write.URI().Name()) app.SaveMenuItem.Disabled = false }, win) saveDialog.SetFileName("untitled.md") saveDialog.SetFilter(filter) saveDialog.Show() } }
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/storage" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" "io/ioutil" "os" "strings" ) /* 用fyne实现简易版typora */ func init() { //设置中文字体:解决中文乱码问题 fontPaths := findfont.List() for _, path := range fontPaths { if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } } type config struct { EditWidget *widget.Entry //编辑框 PreviewWidget *widget.RichText //预览框【富文本】 CurrentFile fyne.URI SaveMenuItem *fyne.MenuItem } var cfg config func main() { a := app.New() win := a.NewWindow("Markdown") edit, preview := cfg.makeUI() cfg.createMenuItems(win) //布局选择左右布局,一边是编辑,一边是预览 win.SetContent(container.NewHSplit(edit, preview)) win.Resize(fyne.Size{Width: 800, Height: 500}) win.CenterOnScreen() win.ShowAndRun() } //初始化界面 func (app *config) makeUI() (*widget.Entry, *widget.RichText) { edit := widget.NewMultiLineEntry() preview := widget.NewRichTextFromMarkdown("") app.EditWidget = edit app.PreviewWidget = preview edit.OnChanged = preview.ParseMarkdown return edit, preview } //添加过滤器,只能打开.md结尾文件 var filter = storage.NewExtensionFileFilter([]string{".md", ".MD"}) //创建主菜单 func (app *config) createMenuItems(win fyne.Window) { //打开文件 openMenuItem := fyne.NewMenuItem("open...", app.openFunc(win)) //保存文件 saveMenuItem := fyne.NewMenuItem("Save...", app.saveFunc(win)) app.SaveMenuItem = saveMenuItem app.SaveMenuItem.Disabled = true //另存为 saveAsMenuItem := fyne.NewMenuItem("Save as...", app.saveAsFunc(win)) fileMenu := fyne.NewMenu("File", openMenuItem, saveMenuItem, saveAsMenuItem) menu := fyne.NewMainMenu(fileMenu) win.SetMainMenu(menu) } //【保存文件】功能 func (app *config) saveFunc(win fyne.Window) func() { return func() { if app.CurrentFile != nil { write, err := storage.Writer(app.CurrentFile) if err != nil { dialog.ShowError(err, win) return } write.Write([]byte(app.EditWidget.Text)) defer write.Close() } } } //【打开文件】功能 func (app *config) openFunc(win fyne.Window) func() { return func() { openDialog := dialog.NewFileOpen(func(read fyne.URIReadCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if read == nil { return } defer read.Close() data, err := ioutil.ReadAll(read) if err != nil { dialog.ShowError(err, win) return } app.EditWidget.SetText(string(data)) app.CurrentFile = read.URI() win.SetTitle(win.Title() + "-" + read.URI().Name()) app.SaveMenuItem.Disabled = false }, win) //添加.md过滤器 openDialog.SetFilter(filter) openDialog.Show() } } //【另存为】功能实现 func (app *config) saveAsFunc(win fyne.Window) func() { return func() { saveDialog := dialog.NewFileSave(func(write fyne.URIWriteCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if write == nil { //user canceled return } if !strings.HasPrefix(strings.ToLower(write.URI().String()), ".md") { dialog.ShowInformation("Error", "Please name your file with a .md extension!", win) return } //save file write.Write([]byte(app.EditWidget.Text)) app.CurrentFile = write.URI() defer write.Close() win.SetTitle(win.Title() + "-" + write.URI().Name()) app.SaveMenuItem.Disabled = false }, win) saveDialog.SetFileName("untitled.md") saveDialog.SetFilter(filter) saveDialog.Show() } } //安装打包程序 //go install fyne.io/fyne/v2/cmd/fyne@latest //fyne package -appVersion 1.0.0 --name MarkDown -appID=.41234 -releas
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/storage" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" "io/ioutil" "os" "strings" ) /* 用fyne实现简易版typora */ func init() { //设置中文字体:解决中文乱码问题 fontPaths := findfont.List() for _, path := range fontPaths { if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } } type config struct { EditWidget *widget.Entry //编辑框 PreviewWidget *widget.RichText //预览框【富文本】 CurrentFile fyne.URI SaveMenuItem *fyne.MenuItem } var cfg config func main() { a := app.New() win := a.NewWindow("Markdown") edit, preview := cfg.makeUI() cfg.createMenuItems(win) //布局选择左右布局,一边是编辑,一边是预览 win.SetContent(container.NewHSplit(edit, preview)) win.Resize(fyne.Size{Width: 800, Height: 500}) win.CenterOnScreen() win.ShowAndRun() } //初始化界面 func (app *config) makeUI() (*widget.Entry, *widget.RichText) { edit := widget.NewMultiLineEntry() preview := widget.NewRichTextFromMarkdown("") app.EditWidget = edit app.PreviewWidget = preview edit.OnChanged = preview.ParseMarkdown return edit, preview } //添加过滤器,只能打开.md结尾文件 var filter = storage.NewExtensionFileFilter([]string{".md", ".MD"}) //创建主菜单 func (app *config) createMenuItems(win fyne.Window) { openMenuItem := fyne.NewMenuItem("open...", app.openFunc(win)) saveMenuItem := fyne.NewMenuItem("Save...", app.saveFunc(win)) app.SaveMenuItem = saveMenuItem app.SaveMenuItem.Disabled = true saveAsMenuItem := fyne.NewMenuItem("Save as...", app.saveAsFunc(win)) fileMenu := fyne.NewMenu("File", openMenuItem, saveMenuItem, saveAsMenuItem) menu := fyne.NewMainMenu(fileMenu) win.SetMainMenu(menu) } //【保存文件】功能 func (app *config) saveFunc(win fyne.Window) func() { return func() { if app.CurrentFile != nil { write, err := storage.Writer(app.CurrentFile) if err != nil { dialog.ShowError(err, win) return } write.Write([]byte(app.EditWidget.Text)) defer write.Close() } } } //【打开文件】功能 func (app *config) openFunc(win fyne.Window) func() { return func() { openDialog := dialog.NewFileOpen(func(read fyne.URIReadCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if read == nil { return } defer read.Close() data, err := ioutil.ReadAll(read) if err != nil { dialog.ShowError(err, win) return } app.EditWidget.SetText(string(data)) app.CurrentFile = read.URI() win.SetTitle(win.Title() + "-" + read.URI().Name()) app.SaveMenuItem.Disabled = false }, win) //添加.md过滤器 openDialog.SetFilter(filter) openDialog.Show() } } //【另存为】功能实现 func (app *config) saveAsFunc(win fyne.Window) func() { return func() { saveDialog := dialog.NewFileSave(func(write fyne.URIWriteCloser, err error) { if err != nil { dialog.ShowError(err, win) return } if write == nil { //user canceled return } if !strings.HasPrefix(strings.ToLower(write.URI().String()), ".md") { dialog.ShowInformation("Error", "Please name your file with a .md extension!", win) return } //save file write.Write([]byte(app.EditWidget.Text)) app.CurrentFile = write.URI() defer write.Close() win.SetTitle(win.Title() + "-" + write.URI().Name()) app.SaveMenuItem.Disabled = false }, win) saveDialog.SetFileName("untitled.md") saveDialog.SetFilter(filter) saveDialog.Show() } } //安装打包程序 //go install fyne.io/fyne/v2/cmd/fyne@latest //fyne package -appVersion 1.0.0 --name MarkDown -appID=.41234 -releas
//安装打包程序
go install fyne.io/fyne/v2/cmd/fyne@latest
//执行打包命令
fyne package -appVersion 1.0.0 --name MarkDown -appID=.41234 -release
//运行app
.\MarkDown
//安装依赖库
go get "github.com/flopp/go-findfont"
在main.go中添加初始化代码:
func init() {
//设置中文字体:解决中文乱码问题
fontPaths := findfont.List()
for _, path := range fontPaths {
if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") {
os.Setenv("FYNE_FONT", path)
break
}
}
}
对于mac系统的朋友来说,如果要想让打包之后的软件可以发给别人运行而不报错,则需要注册一个苹果开发者账号,并且使用付费版(一年大概100$),然后下载一个XCode,通过配置让XCode给我们打包好的软件签名。
- 其他版本的os类似
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。