编写 native 风格的 Qt 程序(8)

前面我们讨论了很多关于编写跨平台程序的若干问题。不过有时候,我们也不得不编写一些与平台相关的代码。为了编写这种更加 native 的程序,我们就来开始详细阐述下编写平台相关的代码所需注意的事项。

编写平台相关的代码,可能会用到 #ifdef 这个预处理指令。我们可以使用 Qt 内置的几个宏,结合 #ifdef 来判断当前是在哪个平台下编译。这也是 C++ 条件编译很重要的一种应用。

Qt 给我们提供了以下几个宏,用于判断当前平台:

  • Q_WS_MAC:Mac OS X
  • Q_WS_X11:X11
  • Q_WS_QWS:Qt for Embeded Linux
  • Q_WS_S60:S60
  • Q_WS_WIN:Windows

我们可以使用下面的代码来判断一下:

#ifdef Q_WS_WIN
// code for Windows
#elseif Q_WS_MAC
// code for Mac OS X

在使用预处理指令进行条件编译之后,我们还可以使用QWidget::winId()函数来获取平台相关的窗口句柄。注意,这个函数是平台相关的,因此,带有这个函数的代码一般都需要事先判断平台,否则很可能会有错误。QWidget::winId()在不同平台的返回值也不一样:

  • Windows 平台下:HWND
  • Cocoa 平台下:NSView*
  • X11 平台下:handle

利用QWidget::winId()的返回值,我们可以调用本地 API。例如使用 HWND 窗口句柄可以调用 Windows Vista 或者 Windows 7 特有的函数。

下面我们给出一些平台相关的程序要点。

Mac OS X

Mac OS X 的应用程序看上去很华丽。在开发 Mac OS X 的程序时,首要要注意使用高分辨率的应用程序图标;其次,像前面曾经提到的,如果要使用系统通知区,需要使用灰度图做图标。

注意一下,Mac OS X 的应用程序菜单栏与 Windows、GNOME 2 或者 KDE 有所不同。Mac OS X 的程序菜单栏是与系统状态栏合二为一的,因此,程序应该提供一个默认的菜单栏。为实现这一目的,我们需要在创建 QMenuBar时,注意不要设置 parent 参数。这样,这个QMenuBar创建出来就是默认菜单栏。

使用QMainWindow::setUnifiedTitleAndToolBarOnMac()函数可以让我们的程序看起来更合理一些:

设置 setUnifiedTitleAndToolBarOnMac 之前

在调用QMainWindow::setUnifiedTitleAndToolBarOnMac()之前,我们可以看到,标题栏和工具栏有一个明显的分隔界线。当我们调用QMainWindow::setUnifiedTitleAndToolBarOnMac()之后,我们的程序就会变得更加自然一些:

设置 setUnifiedTitleAndToolBarOnMac 之后

既然设置这个函数让我们的程序看起来更加合理,为什么 Qt 不默认设置呢?这是因为,当我们设置这个属性时,工具栏变得不可拖动,并且工具栏的 break 也不可见(仔细对比一下上面两个截图)。在全屏情况下,工具栏会被隐藏掉;当程序大小不合适时,自定义组件会被隐藏掉。基于这些原因,Qt 就不会将其设置为默认选项了。请注意下面两个对比图中,当程序尺寸较小时,QToolBar上面组件的显示问题:

小尺寸窗口下的 toolbar

大尺寸窗口下的 toolbar

Mac OS X 的 dock 可以添加菜单。我们可以使用qt_mac_set_dock_menu()函数来实现这一点。

Mac OS X 的 dock 菜单

需要注意的是,这个函数虽然是一个 C++ 函数,但是并没有包含进头文件中,需要你自己去 extern 声明一下:

QMenu *menu = new QMenu;
// Add actions to the menu
// Connect them to slots
...
extern void qt_mac_set_dock_menu(QMenu *);
qt_mac_set_dock_menu(menu);

Qt 会对一些菜单项进行自动排列。比如,如果你的菜单是“关于”、“设置”、“首选项”、“退出”等等,我们可以给它们分配一个角色,Qt 则会根据这些角色对菜单项的顺序作出正确的排列。方法是,设置QAction::menuRole属性,例如:AboutRole、PreferencesRole、QuitRole 或者 NoRole。举例来说,我们可以将“设置”菜单项作为 Mac OS X 的Application::preferences

Mac OS X 的 Preferences 菜单

关于有关 Mac OS X 平台上的介绍就到这里。因为豆子目前也没有 Mac 系统,很多东西也无法亲自测试。这里推荐一篇类似的文章,希望在以后开发时能够加以参考:http://doc.qt.nokia.com/qq/qq18-macfeatures.html

Leave a Reply