教程三 在Go中使用Energy创建跨平台应用 - 状态控制
创始人
2024-02-15 01:08:38
0

本文介绍在Energy中如何像浏览器一样控制状态, 页面的加载、前进、后退、刷新、暂停刷新

前提-需要安装好开发环境参考:教程一环境安装

创建应用

  • 开发环境中 MacOSX平台必须在"GlobalCEFInit"之前设置CEF
  • 设置使用CEF 和 CEF框架目录,生成开发执行应用程序包
    • macapp.MacApp.IsCEF(common.IsDarwin())
  • 全局初始化 每个应用都必须调用的
    • cef.GlobalCEFInit(&libs, &resources)
  • 可选的应用配置
    • cfg := cef.NewApplicationConfig()
  • 指定chromium的二进制包框架根目录, 不指定为当前程序执行目录
    • 环境变量ENERGY_HOME="/app/cefframework" 配置框架所在目录

    if common.IsWindows() {
        //SetFrameworkDirPath 或 配置环境变量 ENERGY_HOME
        //cfg.SetFrameworkDirPath("D:\\app.exe\\energy\\chromium64")
    } else if common.IsLinux() {
        //cfg.SetFrameworkDirPath("/home/sxm/app/swt/energy/chromium")
    }

  • 创建应用
    • cef.NewApplication(cfg)
  • 主进程窗口初始化函数
    • src.MainBrowserWindow()

package mainimport ("embed""github.com/energye/energy/cef""github.com/energye/energy/common""github.com/energye/energy/example/browser-control/src""github.com/energye/golcl/pkgs/macapp"
)//go:embed resources
var resources embed.FS//go:embed libs
var libs embed.FSfunc main() {//开发环境中 MacOSX平台必须在"GlobalCEFInit"之前设置CEF//设置使用CEF 和 CEF框架目录,生成开发执行应用程序包macapp.MacApp.IsCEF(common.IsDarwin())//环境变量 ENERGY_HOME="/app/cefframework" 配置框架所在目录//全局初始化 每个应用都必须调用的cef.GlobalCEFInit(&libs, &resources)//可选的应用配置cfg := cef.NewApplicationConfig()//指定chromium的二进制包框架根目录,//不指定为当前程序执行目录if common.IsWindows() {//SetFrameworkDirPath 或 配置环境变量 ENERGY_HOME//cfg.SetFrameworkDirPath("D:\\app.exe\\energy\\chromium64")} else if common.IsLinux() {//cfg.SetFrameworkDirPath("/home/sxm/app/swt/energy/chromium")}//创建应用cefApp := cef.NewApplication(cfg)//主进程窗口src.MainBrowserWindow()//运行应用cef.Run(cefApp)
}

系统UI和Energy

使用系统组件 golcl 创建控制相关按钮

初始主进程和窗口

  • 在非主进程中有些代码是不必执行的。通过IsMain函数判断是否为主进程
    • commons.Args.IsMain()
  • 使用主浏览器的配置属性对浏览器进行了简单的配置
    • cef.BrowserWindow.Config
  • 使用ChromiumConfig配置开启右键菜单和开发者工具
    • config.SetEnableMenu(true)
    • config.SetEnableDevTools(true)

  • 创建窗口时的回调函数 对浏览器事件设置,和窗口属性组件等创建和修改
  • cef.BrowserWindow.SetBrowserInit 窗口初始函数
  • 在窗口初始函数中
    • 设置更多的窗口属性
    • 窗口的事件
    • 浏览器的事件
  • cef.QueueAsyncCall 函数,在Linux中和操作UI相关的功能中,需要使用该函数包裹住,该函数会将被执行的函数移至主线程中执行。否则操作UI相关或Linux系统中会导致UI线程锁死
  • func controlUI 函数,在SetBrowserInit 函数中调用,主要创建主窗口内的系统UI组件
package srcimport ("fmt""github.com/energye/energy/cef""github.com/energye/energy/common""github.com/energye/golcl/lcl""github.com/energye/golcl/lcl/types"
)//主浏览器窗口
func MainBrowserWindow() {//只有启动主进程才会继续执行if !common.Args.IsMain() {return}//主窗口的配置//指定一个URL地址,或本地html文件目录cef.BrowserWindow.Config.DefaultUrl = "https://energy.yanghy.cn/"//窗口的标题cef.BrowserWindow.Config.Title = "Energy - 浏览器控制"//窗口宽高cef.BrowserWindow.Config.Width = 1024cef.BrowserWindow.Config.Height = 768//chromium配置config := cef.NewChromiumConfig()config.SetEnableMenu(true)config.SetEnableDevTools(true)cef.BrowserWindow.Config.SetChromiumConfig(config)//创建窗口时的回调函数 对浏览器事件设置,和窗口属性组件等创建和修改cef.BrowserWindow.SetBrowserInit(func(event *cef.BrowserEvent, browserWindow *cef.TCefWindowInfo) {//设置应用图标 这里加载的图标是内置到执行程序里的资源文件lcl.Application.Icon().LoadFromFSFile("resources/icon.ico")//在窗体初始化时创建窗口内的组件back, forward, stop, refresh, progressLabel, addr := controlUI(browserWindow)//页面加载处理进度event.SetOnLoadingProgressChange(func(sender lcl.IObject, browser *cef.ICefBrowser, progress float64) {//linux 更新UI组件必须使用 QueueAsyncCall 主线程异步同步cef.QueueAsyncCall(func(id int) {//参数-进度progressLabel.SetCaption(fmt.Sprintf("%v", progress*100))})})//页面加载状态,根据状态判断是否加载完成,和是否可前进后退event.SetOnLoadingStateChange(func(sender lcl.IObject, browser *cef.ICefBrowser, isLoading, canGoBack, canGoForward bool) {//linux 更新UI组件必须使用 QueueAsyncCall 主线程异步同步cef.QueueAsyncCall(func(id int) {//控制按钮状态stop.SetEnabled(isLoading)refresh.SetEnabled(!isLoading)back.SetEnabled(canGoBack)forward.SetEnabled(canGoForward)})})event.SetOnAddressChange(func(sender lcl.IObject, browser *cef.ICefBrowser, frame *cef.ICefFrame, url string) {cef.QueueAsyncCall(func(id int) {addr.SetText(url)})})})//创建窗口之后对对主窗口的属性、组件或子窗口的创建cef.BrowserWindow.SetBrowserInitAfter(func(browserWindow *cef.TCefWindowInfo) {fmt.Println("SetBrowserInitAfter")})
}//控制组件UI
//地址栏和控制按钮创建
func controlUI(browserWindow *cef.TCefWindowInfo) (goBack *lcl.TButton, goForward *lcl.TButton, stop *lcl.TButton, refresh *lcl.TButton, progressLabel *lcl.TLabel, addrBox *lcl.TComboBox) {window := browserWindow.Window//这里使用系统UI组件//创建panel做为地址栏的父组件addrPanel := lcl.NewPanel(window) //设置父组件addrPanel.SetParent(window)addrPanel.SetAnchors(types.NewSet(types.AkLeft, types.AkTop, types.AkRight)) //设置锚点定位,让宽高自动根据窗口调整大小addrPanel.SetHeight(25)addrPanel.SetWidth(window.Width())//创建 按钮-后退goBack = lcl.NewButton(addrPanel) //设置父组件goBack.SetParent(addrPanel)goBack.SetCaption("后退")goBack.SetBounds(0, 0, 35, 25)goForward = lcl.NewButton(addrPanel) //设置父组件goForward.SetParent(addrPanel)goForward.SetCaption("前进")goForward.SetBounds(35, 0, 35, 25)stop = lcl.NewButton(addrPanel) //设置父组件stop.SetParent(addrPanel)stop.SetCaption("停止")stop.SetBounds(35+35, 0, 35, 25)refresh = lcl.NewButton(addrPanel) //设置父组件refresh.SetParent(addrPanel)refresh.SetCaption("刷新")refresh.SetBounds(35+35+35, 0, 35, 25)//创建下拉框addrBox = lcl.NewComboBox(addrPanel)addrBox.SetParent(addrPanel)addrBox.SetLeft(35 + 35 + 35 + 35)                                         //这里是设置左边距 上面按钮的宽度addrBox.SetWidth(window.Width() - (35 + 35 + 35 + 35 + 35 + 35))           //宽度 减按钮的宽度addrBox.SetAnchors(types.NewSet(types.AkLeft, types.AkTop, types.AkRight)) //设置锚点定位,让宽高自动根据窗口调整大小addrBox.Items().Add("https://energy.yanghy.cn")addrBox.Items().Add("https://www.baidu.com")//显示加载进度progressLabel = lcl.NewLabel(addrPanel) //设置父组件progressLabel.SetParent(addrPanel)progressLabel.SetCaption("0")progressLabel.SetBounds(window.Width()-(35+35)-10, 3, 35, 25)progressLabel.SetAnchors(types.NewSet(types.AkTop, types.AkRight)) //设置锚点定位,让宽高自动根据窗口调整大小goUrl := lcl.NewButton(addrPanel) //设置父组件goUrl.SetParent(addrPanel)goUrl.SetCaption("GO")goUrl.SetBounds(window.Width()-35, 0, 35, 25)goUrl.SetAnchors(types.NewSet(types.AkTop, types.AkRight)) //设置锚点定位,让宽高自动根据窗口调整大小//重新调整browser窗口的Parent属性//重新设置了上边距,宽,高window.WindowParent().SetAlign(types.AlNone) //重置对齐,默认是整个客户端window.WindowParent().SetTop(25)window.WindowParent().SetHeight(window.Height() - 25)window.WindowParent().SetWidth(window.Width())//设置锚点定位,让宽高自动根据窗口调整大小//因为窗口大小已调整,这里不能使用 SetAlign 了window.WindowParent().SetAnchors(types.NewSet(types.AkTop, types.AkLeft, types.AkRight, types.AkBottom))//给按钮增加事件goBack.SetOnClick(func(sender lcl.IObject) {browserWindow.Chromium().GoBack()})goForward.SetOnClick(func(sender lcl.IObject) {browserWindow.Chromium().GoForward()})stop.SetOnClick(func(sender lcl.IObject) {browserWindow.Chromium().StopLoad()})refresh.SetOnClick(func(sender lcl.IObject) {browserWindow.Chromium().Reload()})goUrl.SetOnClick(func(sender lcl.IObject) {var url = addrBox.Text()if url != "" {browserWindow.Chromium().LoadUrl(url)}})return
}

go run xx.go

go build

go build -ldflags “-H windowsgui -s -w”

说明

需要你自己下载编译好的框架二进制包,或使用energy命令行工具安装环境,参考教程CEF和Enregy使用
这里面用到了系统UI组件

  1. 首先创建了应用,应用创建属于不管主进程还是渲染进程(子进程)都要执行的代码, 通过NewApplicationConfig配置应用参数,需要你使用(SetFrameworkDirPath)指定框架目录,如果执行文件在框架目录中,则不需要指定.
  2. 创建主窗口,在CEF中主窗口是主进程,UI的主进程,也是brower的主进程,大多数业务逻辑都要在该进程中实现
  3. 在主进程中创建了窗口组件,按钮控制组件,事件监听,窗口属性设置等等.

控制事件

在回调函数BrowserWindow.SetBrowserInit设置事件监听

cef.BrowserWindow.SetBrowserInit(func(event *cef.BrowserEvent, browserWindow *cef.TCefWindowInfo)

设置加载进度改变事件

event.SetOnLoadingProgressChange(func(sender lcl.IObject, browser *cef.ICefBrowser, progress float64)

设置页面加载状态事件

event.SetOnLoadingStateChange(func(sender lcl.IObject, browser *cef.ICefBrowser, isLoading, canGoBack, canGoForward bool)

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...