astilectron之Go语言golang的图形界面

astilectron 是一个Electron应用程序,通过TCP套接字提供API,允许执行Electron的方法以及捕获Electron的事件。

架构

+-----------------------+    TCP    +-------------+    IPC   +---------------------+
+ Client App (any Lang) |<--------->+ Astilectron +<-------->+ win1: (HTML/JS/CSS) +
+-----------------------+           +-------------+     |    +---------------------++
             |                             |            +---->+ win2: (HTML/JS/CSS) +
             |         +----------+        |               |  +---------------------++
             +---------+ Electron +--------+               +-->+ win3: (HTML/JS/CSS) +
                       +----------+                            +---------------------+

语言绑定

语言绑定起着重要作用,astilectron因为它们允许与TCP套接字进行通信,因此与任何语言的API进行交互。

我想为一种新的语言开发语言绑定

大!:)

以下是您需要了解的几件事情:

  • astilectron通常包括下载和解压缩的语言绑定的责任astilectronelectron
  • TCP addr astilectron通过命令行参数发送,因此您的命令行调用时astilectron应该看起来像<path to electron executable> <path to astilectron directory>/main.js <tcp addr>

GO的语言绑定

查看go-astilectronastilectronGO语言绑定


go-astilectron使用GO和HTML / JS / CSS构建跨平台GUI应用程序。这是官方GO绑定astilectron,由供电电子

现实生活中的例子

以下是一系列令人敬畏的项目go-astilectron(如果您正在使用go-astilectron并希望将您的项目列在此处,请提交PR):

  • go-astivid用GO编写的视频工具
  • GroupMatcher计划将人员分配给团体,同时尽可能地履行所有愿望

快速开始

警告:以下代码无法处理可读性的错误。但你应该!

进口 go-astilectron

要导入go-astilectron运行:

$ go get -u github.com/asticode/go-astilectron

开始 go-astilectron

//初始化astilectron 
var  a _ = astilectron。新的(astilectron。选项 {
     AppName <您的应用程序名称>  AppIconDefaultPath <您的.png图标>  AppIconDarwinPath <your .icns图标>  BaseDirectoryPath <您希望供应商安装依赖关系> 
})
推迟一个 关闭()

//开始astilectron 
a。开始()

为了使一切正常工作,我们需要获取2个依赖关系:astilectronElectron.Start()通过下载源并正确设置来处理它。

如果要嵌入二进制来源,以保持唯一的二进制就可以使用NewDisembedderProvisioner功能得到适当的置备并将其连接到go-astilectron.SetProvisioner(p Provisioner)看看这个例子,看看如何使用go-bindata

当您尝试添加自己的应用程序图标时,请注意,您需要2个图标:一个与MacOSX(.icns)兼容的图标,另一个与其他图标兼容(例如.png)。

如果没有提供BaseDirectoryPath,它将默认为可执行文件的目录路径。

大多数方法是同步器,这意味着执行它们时go-astilectron将阻塞,直到它接收到特定的电子事件或者直到整个上下文被取消为止。这种情况.Start()将阻止,直到它收到app.event.ready astilectron事件或直到整个上下文被取消为止。

创建一个窗口

//创建一个新窗口
var  w _ = a。NewWindow http://127.0.0.1:4000 ,与astilectron。 WindowOptions {
    中心:astilectron PtrBool),
    身高:astilectron PtrInt 600),
    宽度:astilectron PtrInt 600
})
W上。创建()

创建窗口时,您需要指定一个URL以及位置,大小等选项。

这是非常简单的,除了astilectron.Ptr*方法,所以让我解释一下:GO不会在json编码时执行可选字段,除非你使用指针,而Electron确实处理可选字段。因此,我添加了帮助方法将int,bool和string转换为指针,并将结果中使用的指针转换为Electron。

添加听众

//在Astilectron上添加一个监听器 
a。(astilectron。 EventNameAppCrash FUNC(E astilectron。事件)(deleteListener布尔){
    astilog。错误 App已崩溃返回
})

//在窗口 
w上添加一个监听器(astilectron。 EventNameWindowEventResize FUNC(E astilectron。事件)(deleteListener布尔){
    astilog。Info Window resized return 
})

除了你可以添加听众到Astilectron以外,没有什么可说的。

玩窗户

//玩窗户 
w。调整大小 200 200
时间。睡觉(时间第二
W上。最大化()

查看窗口文档以获取所有已导出方法的列表

在GO和您的网络服务器之间发送消息

在您的网络服务器中,将以下JavaScript添加到您要与之进行交互的任何页面:

< script >
    //这将等待astilectron命名空间准备好
文档的addEventListener astilectron就绪函数(){ //这将听取GO发送的消息astilectron函数消息){ //这将消息发送回走astilectron发送我很好bro         });    })    
    
        
        
                            
            
            


< / script >

在您的GO应用中添加以下内容:

//听Web服务器 
w发送的消息(astilectron。 EventNameWindowEventMessage FUNC(E astilectron。事件)(deleteListener布尔){
     VAR   消息解组(M)
    astilog。Infof Received message %s ,m)
     return
})

//发送消息到webserver 
w。发送什么事了

就是这样!

注意:不用说,消息可以是字符串以外的东西。一个自定义结构体例如!

处理几个屏幕/显示

//如果有几个显示,将窗口移动到第二个显示器
var  displays = a。显示()
如果 len(显示)> 1 {
    时间。睡觉(时间第二
    W上。MoveInDisplay(显示[ 1 ],5050
}

菜单

//初始化一个新的应用程序菜单
//您可以使用窗口
var  m = a执行相同的操作。NewMenu([] * astilectron。 MenuItemOptions {
    {
        标签:astilectron。PtrStr Separator ),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr Normal 1 )},
            {
                标签:astilectron。PtrStr Normal 2 ),
                的OnClick:FUNC(即astilectron 事件)(deleteListener 布尔){
                    astilog。信息正常2项已被点击返回
                },
            },
            {类型:astilectron。MenuItemTypeSeparator },
            {标签:astilectron。PtrStr Normal 3 )},
        },
    },
    {
        标签:astilectron。PtrStr复选框),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBooltrue),标签:astilectron。PtrStr复选框1 ),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr复选框2 ),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr复选框3 ),类型:astilectron。MenuItemTypeCheckbox },
        },
    },
    {
        标签:astilectron。PtrStr Radio ),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBooltrue),标签:astilectron。PtrStr Radio 1 ),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr Radio 2 ),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr Radio 3 ),类型:astilectron。MenuItemTypeRadio },
        },
    },
    {
        标签:astilectron。PtrStr角色),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr最小化),角色:astilectron。MenuItemRoleMinimize },
            {标签:astilectron。PtrStr关闭),角色:astilectron。MenuItemRoleClose },
        },
    },
})

//检索菜单项
//这将检索“复选框1”项目
mi _  := m。 1 0

//手动添加监听器
//一个OnClick监听器已经直接添加到另一个菜单项 
mi的选项中(astilectron。 EventNameMenuItemEventClicked FUNC(E astilectron。事件 BOOL {
    astilog。Infof菜单项已被点击。‘经过’现在状态%T ,* E。MenuItemOptions经过返回 
})

//创建菜单 
m。创建()

//操纵菜单项 
mi。SetChecked true

//初始化一个新菜单项
var  ni = m。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr插入的),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr插入1 )},
        {标签:astilectron。PtrStr插入2 )},
    },
})

//将菜单项插入位置“1” 
m。插入 1,ni)

//获取子菜单
s _  := m。子菜单 0

//初始化一个新的菜单项 
ni = s。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr追加),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr附加1 )},
        {标签:astilectron。PtrStr附加2 )},
    },
})

//动态附加菜单项追加(ni)

//弹出子菜单作为上下文菜单弹出(&astilectron。 MenuPopupOptions {PositionOptions:astilectron。 PositionOptions {X:astilectron PtrInt 50)中,Y:astilectron PtrInt 50)}})

//关闭弹出 
秒。ClosePopup()

//破坏菜单 
m。毁灭()

要知道的几件事情

  • 当将角色分配给菜单项时,go-astilectron将无法捕获其点击事件
  • 在MacOS上没有窗口菜单,只有应用程序菜单,所以我的建议是坚持一个全球的应用程序菜单,而不是创建单独的窗口菜单

对话框

在您的网络服务器中,添加以下JavaScript之一来实现任何类型的对话。

错误框
< script >
    //这将等待astilectron命名空间准备好
文档的addEventListener ' astilectron就绪'函数(){ //这将打开对话框astilectron showErrorBox我的标题我的内容    })    
        
        

< / script >
留言框
< script >
    //这将等待astilectron命名空间准备好
文档的addEventListener ' astilectron就绪'函数(){ //这将打开对话框astilectron showMessageBox({消息我的信息,标题我的标题 })    })    
        
          

< / script >
打开对话框
< script >
    //这将等待astilectron命名空间准备好
文档的addEventListener ' astilectron就绪'函数(){ //这将打开对话框astilectron showOpenDialog({属性 [ '中openFile ' ' multiSelections ' ],标题我的标题 },功能路径){控制台日志选择路径是    
        
         
            


< / script >
保存对话框
< script >
    //这将等待astilectron命名空间准备好
文档的addEventListener ' astilectron就绪'函数(){ //这将打开对话框astilectron showSaveDialog({标题我的标题 },函数文件名){控制台日志选择文件名,文件名)        } )    })    
        
         
            


< / script >

最终代码

//设置记录器
var  l <您的记录器类型 >
astilog。SetLogger(l)

//启动http服务器 
http。HandleFunc /  FUNC(瓦特HTTP。 ResponseWriter,R * HTTP。请求){
    W上。([] 字节` <!DOCTYPE HTML> 
    <HTML LANG = “EN”> 
    <HEAD> 
        <META字符集= “UTF-8”> 
        <标题>世界,你好</ title> 
    </ HEAD> 
    <BODY> 
        < span id =“message”> Hello world </ span> 
        <script> 
            //这将等待astilectron命名空间准备好
            document.addEventListener('astilectron-ready',function(){ 
                //这将
收到发送的消息通过GO                 astilectron.listen(function(message){ 
                    document.getElementById('message'))。
                    innerHTML = message //这将发送一条消息给GO 
                    astilectron.send(“我是好兄弟”)
                }); 
            })
        </ script> 
    </ body> 
    </ html> `))
})
 http ListenAndServe 127.0.0.1:4000 nil

//初始化astilectron 
var  a _ = astilectron。新的(astilectron。选项 {
     AppName <您的应用程序名称>  AppIconDefaultPath <您的.png图标>  AppIconDarwinPath <your .icns图标>  BaseDirectoryPath <您希望供应商安装依赖关系> 
})
推迟一个 关闭()

//处理退出 
a。HandleSignals()
一个。(astilectron。EventNameAppCrashFUNC(E astilectron。事件)(deleteListener 布尔){
    astilog。错误 App已崩溃返回
})

//启动astilectron:这将下载并设置依赖关系,并启动Electron应用程序开始()

//初始化一个新的应用程序菜单
//您可以使用窗口
var  m = a执行相同的操作。NewMenu([] * astilectron。 MenuItemOptions {
    {
        标签:astilectron。PtrStr Separator ),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr Normal 1 )},
            {
                标签:astilectron。PtrStr Normal 2 ),
                的OnClick:FUNC(即astilectron 事件)(deleteListener 布尔){
                    astilog。信息正常2项已被点击返回
                },
            },
            {类型:astilectron。MenuItemTypeSeparator },
            {标签:astilectron。PtrStr Normal 3 )},
        },
    },
    {
        标签:astilectron。PtrStr复选框),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBooltrue),标签:astilectron。PtrStr复选框1 ),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr复选框2 ),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr复选框3 ),类型:astilectron。MenuItemTypeCheckbox },
        },
    },
    {
        标签:astilectron。PtrStr Radio ),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBooltrue),标签:astilectron。PtrStr Radio 1 ),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr Radio 2 ),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr Radio 3 ),类型:astilectron。MenuItemTypeRadio },
        },
    },
    {
        标签:astilectron。PtrStr角色),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr最小化),角色:astilectron。MenuItemRoleMinimize },
            {标签:astilectron。PtrStr关闭),角色:astilectron。MenuItemRoleClose },
        },
    },
})

//检索菜单项
//这将检索“复选框1”项目
mi _  := m。 1 0

//手动添加监听器
//一个OnClick监听器已经直接添加到另一个菜单项 
mi的选项中(astilectron。 EventNameMenuItemEventClicked FUNC(E astilectron。事件 BOOL {
    astilog。Infof菜单项已被点击。‘经过’现在状态%T ,* E。MenuItemOptions经过返回 
})

//创建菜单 
m。创建()

//在resize 
var  w _ = a上创建一个带有监听器的新窗口NewWindow http://127.0.0.1:4000 ,与astilectron。 WindowOptions {
    中心:astilectron PtrBool),
    身高:astilectron PtrInt 600),
    图标:astilectron PtrStr(<你的图标路径>),
    宽度:astilectron PtrInt 600),
})
W上。(astilectron。EventNameWindowEventResizeFUNC(E astilectron。事件)(deleteListener 布尔){
    astilog。信息窗口大小调整返回
})
W上。(astilectron。EventNameWindowEventMessageFUNC(E astilectron。事件)(deleteListener 布尔){
     VAR   消息解组(M)
    astilog。Infof Received message %s ,m)
     return
})
W上。创建()

//玩窗户 
w。调整大小 200 200
时间。睡觉(时间第二
W上。最大化()

//如果有几个显示,将窗口移动到第二个显示器
var  displays = a。显示()
如果 len(显示)> 1 {
    时间。睡觉(时间第二
    W上。MoveInDisplay(显示[ 1 ],5050
}

//发送消息到服务器的 
时间。睡觉(时间第二
W上。发送什么事了

//操纵菜单项 
时间。睡觉(时间第二
MI。SetCheckedtrue

//初始化一个新菜单项
var  ni = m。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr插入的),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr插入1 )},
        {标签:astilectron。PtrStr插入2 )},
    },
})

//将菜单项插入位置“1”睡觉(时间第二插入1,ni)

//获取子菜单
s _  := m。子菜单 0

//初始化一个新的菜单项 
ni = s。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr追加),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr附加1 )},
        {标签:astilectron。PtrStr附加2 )},
    },
})

//动态追加菜单项 
时间。睡觉(时间第二
秒。追加(ni)

//弹出子菜单作为上下文菜单 
时间。睡觉(时间第二
秒。弹出(&astilectron。MenuPopupOptions {PositionOptions:astilectron。PositionOptions {X:astilectron PtrInt50)中,Y:astilectron PtrInt50)}})

//关闭弹出 
时间。睡觉(时间第二
秒。ClosePopup()

//销毁菜单 
时间 睡觉(时间第二毁灭()

//阻止模式 
a。()

引导

为了方便起见,我添加了一个引导程序来帮助第一个定时器,并避免代码重复。

注意:您不必使用引导,完全取决于您是否使用它。

引导允许您快速创建单窗口应用程序。

使用静态文件和远程信息(最好的方式)

为了使用引导与静态文件和远程消息传递,您必须:

  • 遵循以下项目组织:

      |--+ resources
          |
          |--+ app (contains your static files such as .html, .css, .js, .png, etc.)
      |--+ main.go
    
  • 使用MessageHandler 引导选项来处理远程消息传递

  • 使用remote messaging您的静态文件

使用Web服务器

为了使用带有Web服务器引导程序,您必须:

  • 遵循以下项目组织:

      |--+ resources
            |
            |--+ static (contains your static files such as .css, .js, .png, etc.)
            |
            |--+ templates (contains your templates .html files)
      |--+ main.go
    
  • 使用AdaptRouterTemplateData 引导选项来处理服务器路由

共同

  • 如果您使用RestoreAssets 引导选项,请在您的main()方法之上添加以下注释

      //go:generate go-bindata -pkg $GOPACKAGE -o resources.go resources/...
    

    并在构建二进制文件之前运行以下命令:

      $ go generate main.go
    
  • 使用bootstrap.Run()方法

检查出的例子进行了详细的工作实施例(见实施例下面的特定命令来运行部分)。

我想在行动中看到它!

为了使事情更加清晰,我试图在不同的例子中分割特征

要运行任何示例,请运行以下命令:

$ go run examples/<name of the example>/main.go -v

以下是示例的列表:

  • 1.basic_window创建一个显示静态.html文件的基本窗口
  • 2.basic_window_events播放基本的窗口方法,并显示如何设置自己的监听器
  • 3.webserver_app设置一个基本的网络服务器应用程序
  • 4.remote_messaging向Web服务器发送消息并侦听任何响应
  • 5.single_binary_distribution显示如何go-astilectron在唯一的二进制文件中使用。对于此示例,您必须运行以前的示例之一(以便存在.zip文件)并运行以下命令:
$ go generate examples/5.single_binary_distribution/main.go
$ go run examples/5.single_binary_distribution/main.go examples/5.single_binary_distribution/vendor.go -v
$ go generate examples/8.bootstrap/main.go
$ go run examples/8.bootstrap/main.go examples/8.bootstrap/resources.go -v

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值