Skip to main content

Mac 上的 Alien 控件

Comments

原文链接: [Richard Moe Gustavsen](http://labs.qt.nokia.com/author/richardmg/) - [Alien widgets on Mac](http://labs.qt.nokia.com/2011/02/23/alien-widgets-on-mac/)

直到现在,Qt/Mac 上的每个控件 (widget) 都还是由它们自己的 `NSView` 来支持的。这意味着,Qt 必须将你的程序里控件的层级结构完整映射到 Cocoa 中视图的父子层级结构中。每个 Cocoa 视图接受的本地事件都会被转发给对应的 Qt 控件。然后我们加以处理再重定向以实现 Qt 专门的逻辑,包括隐式或显式的鼠标捕获、弹出等等,最后这些事件再被转换为 QEvent 并以平台无关的方式发送给应用。

Apple 表示你得小心不能用多了 `NSView` ([参考](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaViewsGuide/Optimizing/Optimizing.html)),应该保证视图的数量在 100 以下以获得最优效率。这意味着在你创建重度使用控件的 Qt 应用时,你的应用很容易就会达到这个限制。这样的结果可能不太好,如第一个视频所示。所录的应用故意创建了 2000 个控件,每个都在鼠标经过的时候高亮按钮。如你所见,这个例子不能适应如此大量的控件,造成了很大的延迟。

因为我们知道有些客户确实在使用大量的控件来构建复杂的 UI,这样的限制有时是至关重要的。还好 Qt 针对这个问题有一套叫做 *Alien 控件* ([参考](http://labs.qt.nokia.com/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker/)) 的解决方案。Alien 在 Qt 的 Windows 和 X11 版本中自从 Qt-4.4 就默认启用了,它基本上去掉了要求一个控件必须有一个本地窗口支持的限制。在 Mac 上,这可以转换为 Qt 不要求每个控件必须有一个 `NSView`。这样我们只要用到一个视图 (窗口的内容视图),然后自己把这个视图切分为多个控件,尽可能地跳过 Cocoa 的处理。

这么做的好处有三:其一,我们去掉了在事件达到应用程序之前必须执行的代码。比如不是让 Cocoa 先去找到对应鼠标按下的视图,然后在让 Qt 把事件转发到其他地方 (因为捕获、弹出之类),我们可以直接在 Qt 里处理按下事件;其二,既然大部分的事件处理已经可以从平台相关代码转向平台独立代码,我们希望 Qt/Mac 也能和其他平台保持同步;最后,我们现在遵循了 Apple 的建议不再使用过多的视图了。看来他们说的没错,这真的会拖慢应用。第二个视频展示了使用 Alien 的同一个例子,延迟完全不见了。

Alien 将会在 Qt-4.8 的 Mac (Cocoa) 版本默认启用。

(另外欢迎自己[下载](http://qt.gitorious.org/qt/qt/commits/master)并尝试 Mac 上的 Alien。)

Comments

Subscribe to our blog

Try Qt 6.11 Now!

Download the latest release here: www.qt.io/download

Qt 6.11 is now available, with new features and improvements for application developers and device creators.

We're Hiring

Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.