用node作桌面开发
node的定位是,server-side javascript。
但程序员最爱做的事,就是把一个东西用在不该用的地方。那么,可以把node用在桌面开发上吗?当然可以。
把Javascript用在桌面开发上,早有先例,比如GTK+的gjs,还有Qt的QML(顺带一提,QML代表着桌面开发的另一个方向,a promising way),GNOME3中,也用javascript作为桌面插件的开发语言。
那么为何要多此一举,把node引入到桌面开发上? 因为node的网络编程能力。使用node,你可以十几分钟就写出一个微博客户端来,而且代码简单明了,这种内在的网络能力,是其他所有语言欠缺的。
第一个例子
那么,单刀直入,让我们先看一个hello world:
var gui = require('../lib/gui'); var window = new gui.Window ({ 'title': 'node-gui', 'window-position': 1, 'opacity': 0.5 }); window.show (); window.on ('delete-event', function () { gui.quit (); });
代码很简单, 就像其他所有module一样。
首先,我们使用new Window建立了一个新窗口,参数是窗口property的列表,分别代表标题、位置、透明度,其它属性可以在GTK+文档里查到。 然后,我们调用了show方法。接着,使窗口响应’delete-event’消息,在窗口关闭时退出。
node-gui
代码中引用的module在这里: https://github.com/zcbenz/node-gui/ ,内有详细说明。
可以直接用npm安装:npm install gui
编译时需要注意,你需要GTK+开发库支持。而且因为耍了很多C++11的花枪,你还需要很新的GCC4.6。
为node编写界面库的难点,在于把两种格格不入的事件循环融合起来。我采用的方案,是将GTK+主循环放在新线程中进行,一来简化了逻辑,二来GUI操作向来费时,把GUI操作放在新线程中操作符合异步的要义。
Windows
提到桌面开发,Windows从来是不得不支持的平台。node已经部分支持了Windows,那么使用node-gui的程序能在Windows下跑起来吗?可以,但是需要艰苦卓绝的努力。
node Windows porting尚未实现功能之一,就是native C++ module的支持(如果你想知道原因,是因为模板类成员函数无法导出到额外加载的DLL中),这几乎堵死了我的路。不过经过一番努力,我把node-gui作为node的一部分编译入了node,成功运转了起来。(另外,如果你想亲自尝试的话,为了获得更好的用户体验,最好在编译选项中把Console Window取消掉。)
但是坦言说来,这样没有太大意义,Windows下的GTK+运行库大约有18mb,而且GTK+3也暂时没有Windows的二进制库(原来的贡献者退出了)。为几kb的脚本付出二十来mb的运行时代价,用户不会买账的(也是为何鲜有民用桌面软件采用.NET开发)。
复杂的例子
那么,让我们再接着看一个复杂些的例子,这次我们用上了网络:
var gui = require ('../lib/gui'); var http = require ('http'); new gui.Builder (__dirname + '/download.glade', function (builder) { var window = builder.get ('window' , gui.Window ) ; var download = builder.get ('download' , gui.Button ) ; var url = builder.get ('url' , gui.Entry ) ; var text = builder.get ('text' , gui.TextView ) ; window.setBorderWidth (10); window.show (); window.on ('delete-event', function () { gui.quit (); process.exit (0); }); var onDownload = function () { var sUrl = url.getText (); var options = require ('url').parse (sUrl); var data = ""; var req = http.request (options, function (res) { res.on ('data', function (chunk) { var buffer = text.getBuffer (); var str = String (chunk); buffer.insertAtCursor (str, str.length); }); res.on ('end', function () { download.setLabel ('Download'); download.setSensitive (true); }); }); req.on ('error', function (e) { var message = new gui.MessageDialog ({ 'buttons': 1, 'text': 'Networking Error', 'secondary-text': e.message }); message.show (); message.on ('response', function () { message.destroy (); }); download.setLabel ('Download'); download.setSensitive (true); }); req.on ('response', function () { text.getBuffer ().setProperty ('text', ''); }); req.end (); download.setLabel ('Downloading...'); download.setSensitive (false); }; download.on ('clicked', onDownload); url.on ('activate', onDownload); });
代码我不再详述,github页面有(不太)详细的文档。简单说来,Builder可以从XML文件里直接构造界面,而GUI事件循环也可以和node的网络事件完美融合起来。
界面截图:
未来
这只是一个玩具,开发的唯一目的,就是试试一个idea是否能成(另一个目的是想骗一只阿里云手机来玩,<( ̄︶ ̄)>,可惜不能如愿)。所以,请不要把它用来生产项目中。
而且,因为对GTK+和C++11的依赖,大部分同学到这里,应该都还没编译成功吧…… ╮( ̄▽ ̄)╭
严肃地看来,作为真正的跨平台GUI库,Qt应该是个更好的选择。更严肃地看来,为每个平台单独开发界面库,更符合用户的需求。更更严肃地看来,拿C++写桌面程序,用户才会买账。那都是后话了。
您可能也喜欢: | ||||
部署Node.js的应用 |
Node.js简单介绍并实现一个简单的Web MVC框架 |
用node.js和Websocket来做个多人聊天室吧 |
[实践经验+代码]用node.js和express.js和jade搭建轻型cms系统 |
websocket与node.js的完美结合 |
无觅 |