Thursday, April 16, 2009

Qt 的辩词

Qt 是一个跨平台的 C++ GUI 库,曾经稍微了解了一点,现在重新开始向技术方靠拢,所以再次开始研究这些库,写一些程序准备找工作。我打算比较学习 Qt 和 Gtkmm 这两个 C++ 的库,后者因为依赖于 Gtk+那一套东西,可能学习起来更花时间,于是从 Qt 开始好了。

Qt 的一个特点是提供的 widget 有一个公共的祖先 class,就是 QObject,这并不是一个常意下的 C++ object model,Qt 使用了一个预编译程序 Meta object compiler(简称 moc)扩展了 C++ 的模型,程序员看到的是一个扩展语法下的 class declaration,而 moc 将这个扩展结构解析成为标准 C++ 模型。使用这个方式,而不是 Gtkmm 直接使用 C++ 的方式实现的 GUI library 有他自己的理由

语法

使用 Qt 对 C++ 语法的扩展能够更加简洁、直观的表达 GUI 里面事件驱动过程。其实主要是让新手建立起 signal/slot 的概念,这是 Qt 编程的关键部分。类似扩展语法的如 Borland C++ Builder 也通过类似的手法增强了 C++ object model。

代码自动生成

moc 自动的将 Qt object model 转换成为标准的 C++ model,为程序员提供了一个透明的机制,很多实现相当功能的 C++ 编程技巧(如 procted 成员)、多线程需要注意的保护机制等,将由 moc 自动用一种规范化的方式提供。其实总觉得使用了这种 generator 使得 C++ 编程变得 ugly,但是事实上也可以认为节省了很多精力,可以集中在编程本身,而不是实现这些功能的细节上。另外 Qt 的界面产生程序 user interface compiler (uic)都是 code generator 的典型应用。

GUI 是动态的

C++ 的 object model 是静态的,这意味着一定程度上对 GUI 编程需求的不满足。事实上有很多方式来解决这个问题,Qt 提供的是对程序员透明的,为 QObject 可以动态的添加 property、改变 signal/slot,并且保证 type-safe。

调用开销不是所有的

我们为了获得以上 Qt 提供的所有便捷性的时候应该知道比起使用 template 实现的版本而言,Qt 这一套机制开销大约是前者的 10 倍,但是一般如果使用该功能不是非常频繁(在某个内层循环里面拼命发 signal),这部分一般不会成为瓶颈,往往是程序实现的某些功能本身是开销的主要来源。

其他

使用国际化(i18n)程序需要使用 tr() 以及比 C++ 更好的 RTTI,qobject_cast 都需要使用 moc。

我们将先探索一下 Qt 的 signal/slot 结构。

No comments: