Filed under UI

QT 5试用

  • Build

要直接从Git编译,参考这个文档(居然有中文版本)。从网上下的zip包一大堆问题。然后我在linux和osx下都测试过,居然在osx下容易很多,而在linux下要一大堆依赖。

  • 运行例子

tutorial放在qtquick1目录下,例子还算丰富,文档在这里。运行QML文件需要qtbase/bin/QMLViewer.app。一个QML文件描述了界面显示和事件触发,所以跟HTML很像,但描述语法不类似,我猜只有javascript是一样的。

 

Hello world。可以看出支持Lion的全屏模式,也支持中文。

疑问:1)有HTML的一套,C++的位置在哪里?2)还有CSS么?3)qtwebkit在这里面扮演何种角色?4)Javascript性能如何?真的是第一公民还是如同Gnome Shell只是一个UI的扩展?

玩了下SproutCore

照着文档做了个hello world,运行起来后发现这货完全是浏览器本地运行,压根儿没有服务器的请求。嗯,这下是标准的HTML5了吧。

一个静态的本地应用有什么用呢?有人也有这种疑惑:没有服务器段那如何和数据库打交道呢?如果还是要调用Rails,那表明这个框架只能算上半个。

所以把这东西当作一个C-S的框架比如Swing来看就容易明白了。或者更直接点:它就是为手机上的移动web应用准备的,这个应用可以是http的web应用,也可以是本地的js+css应用。

作为一个C-S框架,比web应用要更关注界面中组件之间的交互,事件绑定和数据绑定是要优先考虑的,而这也是SproutCore的强处。

如果用它通过REST直接连CouchDB之类的文档数据库,倒是一个好的组合。

另外由于HTML5已经足够强大,比如图形和拖放,所以完全可以用javascript来写些“本地”应用。你可能说Swing和Gtk之流已经很成熟了呀?但答案是:HTML5是标准。

所以我关心的一点是SproutCore的模版语言仿佛走上了java JSTL的老路子:

{{#collection SC.TemplateCollectionView contentBinding="Todos.todoListController"}}}
   {{view Todos.MarkDoneView}}
{{/collection}}

又是XML,极端难看啊。如果页面要微调,肿么半呢?

How Webkit render a button

看了这位老兄的blog后,我对webkit也有了兴趣。webkit可以根据布局结构来动态的产生HTML控件,这个在很多可视化开发工具里面可以看到,比如Netbeans,XCode都可以用拖放的方式开发UI。我原来很好奇,这些IDE是如何显示这些控件的呢?因为这些控件和IDE本身的控件有一致外观(OS的主题外观),如果使用普通的API来搞,比如”new JButton()”来构造UI,感觉有点头晕。

找了下,webkit的代码Source\WebCore\platform\gtk\RenderThemeGtk3.cpp是用来创建Gnome 3外观风格的控件,比如方法paintToggle就是对应单选框。我把里面的代码抽取出来,做了个小例子。费了老大劲,因为压根不知道如何得到context和cairo_t这些上下文信息(或者称为状态机,Functional Language反感的就是这个)。GTK的getting started在这里

/**
  this code show how to render a button with gtk 3
  Some code copy from webkit/Source/WebCore/platform/gtk
*/

#include <gtk/gtk.h>
static gboolean
draw_cb (GtkWidget *widget, cairo_t *cr){
  GtkStyleContext *context;
  context = gtk_widget_get_style_context (widget);
  gtk_style_context_save(context);
  gtk_style_context_add_class(context,GTK_STYLE_CLASS_CHECK );
  gtk_style_context_set_state(context, GTK_STATE_FLAG_ACTIVE);

  int i;
  for(i = 0; i < 20; i++){
    gtk_render_check(context, cr, 10*(i+1), 10*(i+1), 10, 10);
  }
  gtk_style_context_restore(context);
}

int
main (int   argc, char *argv[]){
  GtkWidget *window;
  GtkWidget *ebox;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  ebox = gtk_event_box_new ();
  gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), TRUE);
  gtk_container_add (GTK_CONTAINER (window), ebox);
  g_signal_connect_after (ebox, "draw", G_CALLBACK (draw_cb), NULL);
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

上面的截图中可以看到checkbox有native的looking(本人非Nike控),不同的是这些控件只是画上去的(没有JButton这种类的层次结构),没有event binding,也就是MVC只有MV。C的一块可能就由浏览器接过来来统一管理,那得遵循HTML Dom Event Model的规范。

这里不考虑CSS的外观。Gnome 3也是用CSS来控制外观,不知道是不是借鉴webkit。Windows的theme我还没有找到在哪里。

从webkit的代码看其已经支持Gtk+-3.0的back-end,不过Chrome还没有推出相应版本,据说是因为他跟Gtk+-2.0绑的太紧,跟Ubuntu走的太近(Ubuntu没有支持gnome 3)。唉,才几年又轻又快的东东就成了个史前巨无霸。

hotcocoa上手

1. 这是什么?

这是macruby的一个Gem,用来快速开发mac GUI应用。

2. 安装

首先安装macruby,我装的是0.11版本。然后运行sudo macgem install hotcocoa,这个package默认是没有安装的。

3. 运行命令hotcocoa w3,具体参考官方的指南。这里会产生一个和Rails类似的目录。

4.build。 直接编译的话会有问题:Undefined symbols for architecture i386,产生的代码都不能用,很无语。修改gem,在这里/Library/Frameworks/MacRuby.framework/Versions/0.11/usr/lib/ruby/Gems/1.9.2/gems/hotcocoa-0.5.1/lib/hotcocoa/application_builder.rb里面的 archs = RUBY_ARCH.include?('ppc') ? '-arch ppc' : '-arch x86_64',把-arch i386去掉,现在的macruby都已经只有64bit的了。

5. 编译没问题的话就可以看到界面了。不过还没完,试试ruby的closure语法,不然妄走一趟。

def start
  application :name => "W3" do |app|
  app.delegate = self
  window :frame => [100, 100, 500, 500], :title => "W3" do |win|
    title = label(:text => "Hello from HotCocoa.", :layout => {:start => false})
    win << title
    name = text_field(:text => 'you name please')
    win << name
    win << button(:title => 'go') do |b|
       b.on_action do
          title.text = "hi," + name.stringValue
       end
    end
    win.will_close { exit }
end

可以看到,比起objective-c来直观多了,想想看objective-c是怎么操作array的,痛苦。而且这里用closure的方法比用Interface Builder来建立button的事件响应要直观、简单的多,不过就要自己手工组织layout了。能否用HTML中的event bind呢?比如这样dojo.connect(‘buttonId’, “onclick”, function(){…}

这里如果把name.stringValue写成name.text,运行时会有异常:in `’: undefined method `value’ for you name please:NSTextField (NoMethodError),可以看到这里是直接访问cocoa的foundation的。macruby是基于cocoa的运行库的,比如NSString,但是当运行macrake时有个build的过程,时间有点长,难道macruby直接把ruby代码编译成二进制?打开打包好的app文件(这里为W3.app),

可以看到这里即有二进制,也有rb的源代码。可能这里的二进制文件是编译出来的,所以需要一段时间,二进制文件大概作为程序运行的入口,比如运行ruby加载rb文件,这个和有些exe结尾的可执行java程序相像。只是这样打包后coding-build-test的周期就长了,还是“刷新浏览器”的方式爽啊,当然有firebug这种工具就更爽了。