使用Haskell,wxWidgets(通过wxHaskell)或GTK(通过Gtk2HS)开发GUI应用程序更好?
每种的优点和缺点是什么?它取决于您所针对的平台(我主要是在OS X上工作,但我希望我的程序也适用于Linux和Windows)吗?
答案 0 :(得分:23)
[免责声明:我是wxHaskell维护者]
两者都是稳定且相当完整的GUI绑定,您可以放心地选择大多数项目。两者都有一定程度的“更高级别”Haskell绑定,但在这两种情况下,您都需要采用相当命令式的“C”式编码来完成工作。我的印象是wxHaskell允许你在更高级别的绑定中花费更多的时间,但我没有做太多的GTK2HS,无论如何,你肯定发现自己正在为两个库的包装器的瘦端工作 - 我认为整个编程的“复杂性”在两种情况下都是相似的。
因此,让我们把基本功能作为一个给定,并专注于差异。请注意,我真的相信GTK2HS是一项出色的工作,如果您选择它,您会很高兴。我下面说的大部分内容都是对差异的个人看法,以及为什么我选择自己和wxHaskell一起工作。
GTK2HS有一个更大的团队正在努力,并且更经常地发布。 wxHaskell不经常更新,但核心团队是活跃的,并且有定期的错误修正,但主要的新功能的添加速度比我们想要的慢得多(我们都有日常工作)。
wxHaskell在所有支持的平台上提供真正的本机应用程序外观。当然,GTK2HS在Linux上是原生的,并且在Windows上具有非常好的原生主题(即足以满足所有人的需求......),但在OSX上具有GTK外观和感觉,并且依赖于安装X11。我相信OSX“原生”GTK库正在开发中,但被认为相对不成熟。一旦稳定,GTK2HS应该能够轻松地从相同的“部分原生”外观中获益(例如GTK OSX screenshot)。
如果你不在Linux上,那么wxHaskell可能会更容易构建(如果你是Linux托管的话,GTK2HS可能会更容易),但是两者都非常复杂,说实话,因为存在大量的依赖关系两种情况。基于wxHaskell分发应用程序稍微容易一些(恕我直言),因为它具有较少的库依赖性。我主要在Windows上使用InnoSetup分发应用程序,在OSX上使用App捆绑包。我承认,只需要少量的额外工作,GTK2HS也可以这样做,所以这可能是支持wxHaskell的最薄弱的论据。
我个人认为wxHaskell对闭源(例如商业)开发更友好。当然,这是无休止的火焰战争的主题,所以我只会说wxHaskell属于wxWidgets license,它明确允许闭源开发。 GTK2HS是LGPL,因此您需要询问您的律师 - 尽管我必须明确表示许多人和公司已经得出结论LGPL与商业开发兼容;我工作的公司的律师得出的结论是,这对我们的项目来说是不合适的。
我认为如果Linux是我的主要开发和交付平台,我可能会使用GTK2HS。但事实并非如此:我主要向Windows提供偶尔的OSX,我认为wxHaskell与这些平台更匹配,尽管两种选择都支持所有三种平台。
我希望这会帮助您做出选择。
答案 1 :(得分:4)
需要考虑的是,目前让wxHaskell在Mac OS X上本地工作稍微容易一些.GTK2HS依赖于GTK,它确实在Mac OS X上使用本机小部件进行实现,但是这种实现并不像Mac OS X的wxWidgets实现是。
因此,如果你想开发没有X11.app运行的代码,目前使用wxHaskell会稍微好一些。
但请注意,这种情况正在迅速改变: http://www.haskell.org/haskellwiki/Gtk2Hs#Using_the_GTK.2B_OS_X_Framework 展示了如何在Mac OS X上使用原生GTK +的GTK2HS。
GTK2HS的一个优点是它的GLADE支持,使得简单UI的开发非常快。 wxHaskell中更高级别的组合器可以减轻大部分优势,但它们确实需要更深入地了解您希望界面的外观和行为,因此更难以探索性方式使用。
答案 2 :(得分:3)
我的信息非常不完整,但由于你还没有答案,也许不完整的信息总比没有好。
要问的问题是:工具包是否只是C类功能的包装器,还是有一个额外的层为工具箱提供了更“原生Haskell”的API?当wxHaskell首次在Haskell研讨会上宣布时,原生Haskell API的开发看起来非常有前景,但仍然不完整。看起来好像wxHaskell的“Haskellized”API仍在使用,而Gtk2Hs项目根本没有提到这个问题。出于这个原因,我建议使用wxHaskell。
答案 3 :(得分:0)
就个人而言,我会研究某种Reactive包/扩展。它似乎更接近范式。您可以以声明方式执行此操作,而不是强制指定图形内容。示例(不代表任何特定语言或实现):
x, y, z :: Int
click, buttonclicked :: Bool
x = <X coordinate of mouse>
y = <Y coordinate of mouse>
click = <Whether mouse button is currently being pressed>
z = x + y
buttonclicked = (x == 10 && y == 10 && click)
每次x和y更改时,Buttonclicked和z都会自动更新。
然后你可以在某处找到类似的逻辑:
if buttonclicked then <do something> else <do something else>
尽管如此,这一切都非常模糊。只需研究一些真实的反应接口