🕵️‍♂️ Go语言GUI框架迷局:寻找RAD工具的“真命天子”

自上世纪80年代以来,我一直徜徉在代码的世界里。近年来,我一直在探索用Go语言编写GUI程序的各种可能性,尤其希望能找到合适的工具来构建跨平台桌面GUI软件。当然,如果能用同一套技术开发移动版本,那就更令人兴奋了,毕竟,节省开发人员宝贵时间和精力的技术,谁不爱呢?

然而,一番探索下来,我却发现了一个残酷的事实:Go语言目前还没有一个真正好用的GUI框架! 这实在令人惋惜,因为除了GUI这一点,Go语言几乎完美契合了我对易用、快速的应用程序开发工具的所有想象,就像我曾经钟爱的REALBasic(现在更名为价格不菲的Xojo)那样。遗憾的是,到目前为止,还没有任何一个框架或语言+IDE+框架的组合能够超越REALBasic带给我的高效开发体验。

我并非没有尝试过其他的选择。Lazarus和Object Pascal也曾进入我的视野,但Object Pascal毕竟年岁已高,语言本身的局限性难以忽视,而且有时还需要手动管理内存,这对于桌面GUI应用程序来说简直是噩梦。我也曾考虑过其他我比较熟悉且喜欢的语言。

Racket拥有非常完善的GUI工具包,我曾经用它编写和维护过多年的GUI应用程序。然而,用Racket开发的GUI应用程序反应迟钝,启动时间也令人捉急,这使得它在开发“轻快敏捷”的小型GUI应用程序时显得力不从心。

Ada给我的感觉就像是在不断积累技术债务,而且缺乏第三方库的支持。它唯一还算过得去的GUI选项是GTK3。我还尝试过CommonLisp,但它总是给我一种“拼拼凑凑”的感觉,而且现有的第三方库缺乏文档,可靠性也值得怀疑。至于Rust,我已经学习了它的语法,甚至从头到尾啃完了Klabnik和Nichols合著的那本“巨著”,但我不得不承认,Rust给我的感觉是过度设计,并不吸引我。它是否真的适合开发高完整性系统,我持保留意见(我仍然推荐Ada/Spark来完成这类任务)。此外,Rust在GUI编程方面没有任何优势,而且它的社区氛围也让人不敢恭维。

所以,在一番权衡之后,我还是选择了Go语言来开发一个大型项目,而GUI库的选择也提上了日程。以下是我对Go语言GUI框架的个人看法,仅供参考。

🎭 各显神通:Go语言GUI框架大比拼

在Go语言的世界里,GUI框架虽然数量不多,但也称得上是“百花齐放”。下面,我将逐一介绍这些框架的特点、优缺点以及适用场景,希望能帮助读者朋友们找到适合自己的那一款。

1️⃣ Fyne:叫好不叫座?

  • 官方网站: https://fyne.io/
  • 测试情况: 经过广泛测试
  • 评分: 5/10
  • 更新/修复频率: 频繁且迅速
  • 推荐指数: 仅推荐用于移动应用程序开发

Fyne基本上是一个人带着一群合作者的成果。我的感受是,Fyne的开发者们更擅长推广他们的框架,而不是编写GUI框架。Fyne在设计上存在一些根本性的缺陷。其中最大的问题是,他们试图用完全相同的代码来开发桌面和移动应用程序。要知道,手机和平板电脑的尺寸和交互方式与桌面电脑截然不同,这种“一刀切”的想法显然行不通。桌面应用程序与移动应用程序有着本质的区别,这是Fyne开发者们需要正视的问题。

由于Fyne的设计理念存在偏差,他们做出了一系列令人费解的选择。例如,他们将布局与控件分离,这使得一切都变得异常复杂,使用起来一点也不简单。Fyne提供的布局机制倾向于将其内容最小化,控件只存储最小尺寸(所有控件的默认值),而没有首选尺寸或最大尺寸。此外,Fyne的控件没有锁定顶部、左侧、底部、右侧或其他合理的机制来控制它们在嵌入窗口或面板大小调整时的行为。Fyne还没有Z-order机制来控制控件之间的切换顺序。

另一个大问题是,Fyne缺乏合理的文件路径抽象。开发者们坚持认为所有东西都应该是URL,显然没有意识到URL标准并没有以跨平台的方式指定包含卷信息的绝对路径。虽然URI方案有一些扩展可以使用盘符,Fyne也使用了一些他们认为合适的方案,但这些基于/\的本地文件系统路径转换存在很多问题。例如,如何处理可移动驱动器?如何处理Windows上的盘符?如何构造路径、遍历文件系统?到目前为止,Fyne并没有提供任何帮助,甚至坚持认为每个URI都代表一个任意的资源,你不应该假设它指向一个文件,它也可能是一个网络资源。难道网络访问和文件访问真的可以一概而论吗?

总而言之,Fyne并不适合开发桌面应用程序,尽管它在移动平台上可能还不错。用Fyne很难设计出复杂的桌面应用程序界面。默认情况下,Fyne应用程序会违反所有平台上的人机界面指南,而开发者们似乎对此感到非常自豪。你将不得不花费数天甚至数周的时间来为一些简单的事情创建自己的专用布局算法,而这些事情在其他合理的、标准的布局系统中只需几分钟或几小时就能完成。

2️⃣ Gio:未来可期

  • 官方网站: https://gioui.org/
  • 测试情况: 未经测试
  • 评分: 6/10
  • 更新/修复频率: 一般,速度较慢
  • 推荐指数: 很有潜力,但我还没有对其进行详细测试

Gio是一个非常有前途的立即模式GUI框架,它也包含一些状态ful控件。一些人认为它是Fyne的良好替代品,它拥有你在应用程序中期望的大多数控件。在我看来,Gio的使用方法似乎有些复杂和繁琐——如果你查看示例代码,就会发现即使是简单的入门程序也需要编写大量的样板代码。然而,Gio最大的缺点是缺乏文档,这使得它很难上手,你在一开始可能会迷失方向。尽管如此,我仍然计划在将来找个时间试用一下Gio,至少将其作为GIU的替代方案进行测试。我还没有测试过它对编辑器控件的支持程度——框架是否能够支持复杂的文本编辑(多行文本、富文本甚至嵌入图像)是衡量GUI框架优劣的试金石之一,因为多行文本编辑是目前为止最难正确实现的功能。我还没有仔细研究过Gio的代码,但我猜测它在这方面的表现应该与Giu类似。

3️⃣ Giu:小项目利器

  • 官方网站: https://github.com/AllenDang/giu
  • 测试情况: 经过广泛测试
  • 评分: 6/10
  • 更新/修复频率: 一般,速度较慢
  • 推荐指数: 推荐用于小型项目,但在投入使用前请仔细检查其局限性

Giu是一个不太为人知的立即模式GUI框架,它基于imgui的Go语言分支,使用了imgui的C语言库。Giu非常易于使用,在我测试过的所有GUI框架中,它可能是让我最快获得满意结果的框架,尽管它的速度比不上Lazarus这样的传统RAD工具。Giu拥有你可能需要的大多数控件,但有两个明显的缺陷:

  • 缺少文件对话框: Giu没有提供文件和文件夹选择/保存对话框,以及其他一些常见的简单对话框。我已经设法实现了一些替代方案,足以满足我的使用场景,但你应该意识到,没有原生的文件对话框是一个严重的限制,可能会带来其他问题(例如,缺乏与“记住上次文件访问”功能、拖放功能等的集成)。
  • 多行文本框不支持自动换行: 我已经找到了解决这个问题的方法,但还没有在Github上公开代码。

因此,你应该意识到这可能是一个相当大的限制。然而,与Fyne不同的是,Giu的所有默认设置都很合理,而且用它很容易就能创建出简单到中等复杂度的GUI,例如包含列表、一些编辑字段、按钮、组合框或单选按钮、菜单以及一两个窗口拆分器的界面。Giu的外观和感觉一点也不原生,但总体来说还不错。你可以访问底层的imgui库,但要注意,imgui本身非常简陋,Go语言版本没有像C语言版本那样提供高级的状态ful控件。

4️⃣ GTK:老牌劲旅

  • 官方网站:
    • GTK3: https://github.com/gotk3/gotk3
    • GTK4: https://github.com/diamondburned/gotk4
  • 测试情况: 测试过GTK3
  • 评分: 7/10
  • 更新频率: 自动生成
  • 推荐指数: GTK4可能是目前开发大型复杂桌面应用程序的最佳选择,这类应用程序通常使用Qt来开发

5️⃣ IUP:简单易用

  • 官方网站: https://github.com/matwachich/iup
  • 测试情况: 未经测试
  • 评分: 5/10
  • 更新频率: 从未更新
  • 推荐指数: IUP在Linux和Windows平台上口碑不错,它可能是一个比GTK更容易部署的替代方案,值得一试

6️⃣ Qt:受 licensing 限制

  • 官方网站: https://github.com/therecipe/qt
  • 测试情况: 未经测试
  • 评分: 对于没有商业许可的专有软件来说,Qt的得分为4/10,但对于GPL软件来说,它可能是一个不错的选择
  • 更新/修复频率: 很少更新,速度较慢
  • 推荐指数: 由于许可证问题,Qt只适合开发GPL软件

7️⃣ Unison:值得关注

  • 官方网站: https://github.com/richardwilkes/unison
  • 测试情况: 未经测试
  • 评分: 无法评分(演示程序在编译skia时出错,因此无法提供截图)
  • 更新/修复频率: 正在开发中

我最近才发现Unison,目前还无法对其做出评价。Unison看起来是一个不错的非原生GUI框架,它提供了许多标准控件,并且正在为作者的个人项目进行开发。Unison的代码看起来非常清晰易懂,所以我建议你尝试一下。我以后也会对它进行更广泛的测试。当然,Unison目前还不能用于生产环境,尤其是大型GUI项目。

8️⃣ Wails:Web 开发者的福音

  • 官方网站: https://wails.app/
  • 测试情况: 未经测试
  • 评分: 7/10
  • 更新/修复频率: 频繁且迅速
  • 推荐指数: 如果你本来就擅长Web开发,那么我强烈推荐你尝试一下Wails

Wails是这份清单中唯一的基于Web的GUI框架,因为它不是我的首要选择。Wails允许你使用Go语言编写后端代码,并使用任何你喜欢的Web框架来开发GUI。Wails会自动将Go代码与HTML中的Javascript代码链接起来,并渲染HTML/JS代码。最终的产物是一个功能齐全的桌面应用程序。我在很多地方都看到过人们推荐Wails,并将其与各种前端库结合使用。

如果你本来就擅长开发Web应用程序,那么我强烈推荐你尝试一下Wails。我的目标是使用一个允许我完全使用Go语言开发所有组件的GUI库,因此Wails不在我的考虑范围之内。然而,基于Web的界面可以做得非常漂亮,而且熟悉Web设计的开发者可能会发现Wails比任何非原生的、纯Go语言的GUI库(通常基于Open GL后端渲染引擎)都要好用。如果你希望你的应用程序看起来像一个网页(或者希望保留将其变成真正的Web应用程序的选项),那么Wails可能是最容易实现这一目标的选择。

🏆 总结:路漫漫其修远兮

总的来说,Go语言的GUI框架选择还是比较有限的。我选择Giu来开发一个项目,但其实选择Gio也无妨。但我必须承认,我并不喜欢立即模式GUI。如果你的GUI比较复杂,你最终将不得不编写额外的“布局缓冲区”粘合代码来维护状态。例如,我需要从sqlite数据库中获取和设置数据,但Giu的文本字段只支持字符串,所以我必须单独维护字符串,并在适当的时候从数据库中获取/更新数据。也许GTK4是更好的选择,我最终可能会改用GTK4。我将来也可能会再给Fyne一次机会,但我不抱太大希望。Fyne的设计理念过于固执,而且方向也不对。我还考虑过在正式项目中尝试Wails。对我来说,学习Wails的成本会很高,因为我的Web设计知识还停留在上世纪90年代末。然而,Wails在灵活性和重新设计方面的优势可能值得我为之付出努力。

📚 参考文献

  • Fyne: https://fyne.io/
  • Gio: https://gioui.org/
  • Giu: https://github.com/AllenDang/giu
  • GTK:
    • GTK3: https://github.com/gotk3/gotk3
    • GTK4: https://github.com/diamondburned/gotk4
  • IUP: https://github.com/matwachich/iup
  • Qt: https://github.com/therecipe/qt
  • Unison: https://github.com/richardwilkes/unison
  • Wails: https://wails.app/

原文链接: https://medium.com/@balle.johannes/no-good-go-gui-9f54813e9bf

0 0 投票数
Article Rating
订阅评论
提醒
0 评论
最多投票
最新 最旧
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x