外部-Golang的GUI

同事们,您好!

大约一个月前,我在这里的一个线程上发表了有关GUI框架的文章,该文章提供了一种技术,该技术基于将(tcp / ip或其他方式)连接到充当一种GUI服务器的外部进程,从而为不同的编程语言创建GUI框架。 在这里,我想提出这个想法的具体实现-用于Golang - External的新GUI框架。

如果已有许多可用的工具,为什么需要为Golang编写新的GUI? 首先,因为它们都不适合我。 需要一些东西来创建跨平台的桌面应用程序,以使每个平台看起来自然。 如果可能的话,不会造成太大的麻烦,并且具有最小的依赖关系-我致力于一种极简主义的方法。

这个列表指导我。 由于不符合跨平台的要求,两个职位-appwalk被立即划掉。 经过一番思考,他拒绝了那些基于html / css / javascript的代码。 首先,对我而言,将桌面应用程序构建为网页似乎有些不寻常,其次,它们也带来了相当繁重的引擎。 因此,例如, go-astilectrongowd分别基于Electronnw.js ,而它们又分别基于node.js。 想像一下,即使要运行一个小的实用程序,最终用户必须安装多少东西? 除非从这个角度来看, 围棋看起来更好:站在它后面的Sciter并不是那么可怕。

Go-gtkgotk3基于GTK。 这些显然是完全制作的软件包,但是我也拒绝了它们,因为我认为,在Windows下使用GTK并不是最佳解决方案。 GTK窗口在Windows下看起来不是本地的。 Qt绑定当然是一项功能强大的事情,但是相当复杂,而且尺寸庞大……当我读到:“您还需要2.5 GB的可用RAM(仅在初始设置期间需要)和至少5 GB的可用磁盘空间”时,最后的疑问消失了。 Go本身占用的空间减少了十倍。 然后是许可限制:“与LGPL许可的这种绑定不适用于打算分发给公众的封闭源应用程序”。

我们还剩下什么呢? Ui可能是一个不错的选择,但它仍处于中间Alpha阶段。 Fyne看起来也不错,但是似乎还没有准备好。 一方面,“ Fyne完全使用矢量图形构建”,另一方面,“ EFL Windows软件包当前更旧,因此您将看不到Fyne应用程序的矢量图形部分”,这有点令人尴尬。 好吧,我不喜欢在Windows上安装EFL (基于Fyne的图形库),需要MSYS

简而言之,在充分尊重这些程序包的作者及其工作成果的前提下,我没有为自己选择任何东西,并且出于良知,我继续着我想做的事情-编写了一个新的GUI框架-External

正如我在上一篇文章中已经写到的那样, External并不能单独实现GUI元素,它为此使用了一个单独的应用程序,一个充当GUI服务器的单独进程,该应用程序称为GuiServer外部启动它,通过tcp / ip加入它,发送命令/请求以创建窗口和小部件,对其进行操作等,并从中接收消息。

这是一个简单的程序,它使用传统的题词Hello,world创建一个窗口:

package main import egui "github.com/alkresin/external" func main() { if egui.Init("") != 0 { return } pWindow := &egui.Widget{X: 100, Y: 100, W: 400, H: 140, Title: "My GUI app"} egui.InitMainWindow(pWindow) pWindow.AddWidget(&egui.Widget{Type: "label", X: 20, Y: 60, W: 160, H: 24, Title: "Hello, world!" }) pWindow.Activate() egui.Exit() } 

Init()函数启动GuiServer并将其加入。 可以将一个字符串参数传递给它,该参数在必要时确定GuiServer的名称及其路径,IP地址和端口以及日志记录级别。

InitMainWindow()使用指定的参数创建主应用程序窗口。 方法AddWidget()-添加标签类型的窗口小部件。

激活()-在屏幕上显示一个窗口,并使程序进入待机模式。
窗口和窗口小部件都在窗口小部件结构中定义-我没有为每个对象创建单独的结构,因为 鉴于Go没有继承,我没有找到实现此目的的便捷方法。 该结构包括大多数小部件通用的字段和map [string]字符串,其中包含特定于特定对象的属性:

 type Widget struct { Parent *Widget Type string Name string X int [...] Font *Font AProps map[string]string aWidgets []*Widget } 

这种结构的方法包括熟悉的AddWidget()以及SetText(),SetImage(),SetParam(),SetColor(),SetFont(),GetText(),Move(),Enable()等)。我想提到SetCallBackProc()和SetCallBackFunc()-用于设置事件处理程序。
在这里列出所有功能,结构和方法是不合适的,因为这样做更精确。 必须有文件。 我只想说一些一般性的想法:

Menu(),MenuContext(),EndMenu(),AddMenuItem(),AddMenuSeparator()-一组用于创建菜单,主菜单或上下文的函数。
EvalProc(sCode字符串),EvalFunc(sCode字符串)传递一个Harbor代码片段(可以是多行),以在GuiServer上执行-一种内置脚本语言的实现。
OpenForm(sPath字符串)-基于HwGui Designer创建的xml文件中的描述创建一个窗口。
OpenReport(sPath字符串)-根据HwGui Designer创建的xml文件中的描述打印报告。
MsgInfo(),...,SelectFile(),SelectColor(),SelectFont()-调用标准消息框和对话框。
InitPrinter()和一组打印机结构方法:Say(),Box(),Line()等为打印提供预览功能。

这是当前支持的小部件的完整列表:
标签,编辑,按钮,检查,单选,radiogr,组,组合,位图,线,面板(设计用于在其上托管其他小部件),paneltop,panelbot,ownbtn(ownerdrawn按钮),拆分器,updown,树,进度,标签,浏览(表,很多人称其为),cedit(使用高级功能进行编辑),monthcal。

所有这些都连同其他属性一起列在extwidg.go的init()函数中。 每个属性均可访问-这些属性通过Widget.AProps设置。 这些小部件中的许多具有其他属性,尤其是浏览丰富的属性。 可以使用SetParam()方法分别设置它们。

外部的体积很小,它是用纯Go语言编写的,除了一些标准的软件包外,它不会提取其他软件包。 GuiServer提供了跨平台,可以在Windows,Linux / Unix,Mac OS上进行编译。 使用此外部模块确实带来一些不便,您需要从源代码进行编译,或者从我的网站下载完成的模块并将其放在PATH指定的目录中。 顺便说一句,它很小-对于Windows来说只有大约一半半字节,对于Linux来说只有大约三兆字节。

外观如何,我将向您展示一个小型ETutor应用程序的示例-Golang教程。 该程序以树的形式展示了Go上的代码片段集合。 可以编辑代码,运行执行。 没什么特别的,但是很舒服。 可以补充收藏,添加新收藏。 现在,已经(尚未完全)收集了Go之旅,Go实例访问以及有关External本身的几个示例。 ETutor还可以用于例如在Go上组织一组实用程序。 因此,截图。

Windows 10:



Debian,Gnome:



最后,链接:

外部在Github上
Github上的GuiServer
GitHub上的ETutor
在我的网站上有关GuiServer的页面,您可以在其中下载现成的二进制文件
https://groups.google.com/d/forum/guiserver-一个讨论与GuiServer和外部相关的所有问题的小组
关于Habré上GuiServer的文章

Source: https://habr.com/ru/post/zh-CN431490/


All Articles