临近春节,更新也慢了许多。今天再来写一篇,不知道会不会是春节前的最后一篇了。豆子先祝大家新春愉快!

我们知道,HTML 仅仅被定义为一种内容布局的语言。也就是说,HTML 应该做的,是告诉浏览器,这个东西应该放在这里,那个东西应该放在那里。至于这些东西该怎么显示,例如,用红色还是用蓝色,这样的显示的定义应该交给 CSS 去做。所以,在新近版本的 HTML 中,font、color 这样的标签和属性已经不被推荐使用了。同样,在 Qt 中也有这么一个样式表,被称为 style sheet——这其实和 CSS 如出一辙。不仅名字相似,就连语法之类也相当雷同。

style sheet 虽然很好用,但是,我们应该提出几个需要注意的地方。style sheet 应该被小心使用,因为它会打破系统正常的 look and feel。还记得我们前面提到的那个同普通 Windows 程序格格不入的 safari 吗?所以在使用 style sheet 时应该尽量选用系统调色板,而不是自己定义一个另类的颜色。

关于 style sheet 语法更详细的手册,我们可以到这里去查看。当然,如果你安装的是 mingw 版本的 Qt(Windows 平台),这个文档已经在 Qt Help 里面了。在这里,我们不去详细介绍具体的语法细节,而是专注于如何正确使用 style sheet。所以,如果你有的语法看不懂,请自行查阅文档了解。

自己定义 label 的颜色固然很简单,请看以下代码:

  1. #include <QtGui> 
  2.  
  3. int main(int argc, char *argv[]) 
  4.     QApplication app(argc, argv); 
  5.  
  6.     QLabel label; 
  7.     label.setText("Hello, style sheet!"); 
  8.     label.setStyleSheet(QString("color:red")); 
  9.     label.show(); 
  10.  
  11.     return app.exec(); 

我们将 label 的颜色使用 style sheet 定义为红色,运行起来如下图所示:

这种预定义的颜色很简单,然而,如果我想用个系统颜色呢?比如,我希望是系统高亮的颜色?难道还得自己去找高亮色的 RGB 值吗?正确的做法是,使用系统调色板,如下代码所示:

  1. label.setStyleSheet(QString("color:palette(highlight)")); 

这样,我们直接从系统调色板中得到高亮色,即便是不同的系统,也不需要修改任何代码。以下是在 Windows 7 上面的运行结果:

即使你必须使用自定义颜色,也不应该将颜色硬编码。而是使用一种变通的方式,例如:

  1. QColor color(128, 200, 128); 
  2. label.setStyleSheet(QString("color:%1").arg(color.name())); 

这样做的好处是,你可以很方便地让用户选择颜色,存入配置文件,并且在以后的启动中从配置文件中读取 color 的值,而不需要修改代码。

使用 style sheet 可以做出很漂亮的显示效果。由于使用 style sheet 要比 前面说的自定义 style 简单得多,因此,我们还是建议多多使用这一技术。下面,我们制作一个苹果风格的前进/后退按钮。效果如下:

为了制作这一按钮,我们需要以下四幅图片:

按照从上向下的顺序分别命名为 btn_left.png, btn_left_pressed.png, btn_right.png 和 btn_right_pressed.png。然后,我们用下面的代码:

  1. #include <QtGui> 
  2.  
  3. int main(int argc, char *argv[]) 
  4.     QApplication app(argc, argv); 
  5.  
  6.     QWidget segmentedButton; 
  7.     QToolButton *backButton = new QToolButton(&segmentedButton); 
  8.     QToolButton *forwardButton = new QToolButton(&segmentedButton); 
  9.     segmentedButton.setLayout(new QHBoxLayout); 
  10.     segmentedButton.layout()->setSpacing(0); 
  11.     segmentedButton.layout()->setMargin(0); 
  12.     backButton->setStyleSheet(QString("QToolButton{border-image:url(:/btn_left.png)}" 
  13.                                       "QToolButton:pressed{border-image:url(:/btn_left_pressed.png)}")); 
  14.     forwardButton->setStyleSheet(QString("QToolButton{border-image:url(:/btn_right.png)}" 
  15.                                       "QToolButton:pressed{border-image:url(:/btn_right_pressed.png)}")); 
  16.     backButton->setFixedSize(28, 23); 
  17.     forwardButton->setFixedSize(28, 23); 
  18.     segmentedButton.layout()->addWidget(backButton); 
  19.     segmentedButton.layout()->addWidget(forwardButton); 
  20.  
  21.     QWidget win; 
  22.     win.setLayout(new QHBoxLayout); 
  23.     win.layout()->setSpacing(0); 
  24.     win.layout()->setMargin(0); 
  25.     win.layout()->setAlignment(Qt::AlignLeft); 
  26.     win.layout()->addWidget(&segmentedButton); 
  27.     win.show(); 
  28.  
  29.     return app.exec(); 

即可得到上图所示的效果。注意,我们之所以把 segmentedButton 又放入一个新的 widget 里面,是由于 Windows 平台下的窗口有一个最小值。如果直接调用 segmenedButton.show(); ,由于这个最小值的缘故,两个 button 并不会在一起。使用这一技术,我们很容易制作出很漂亮的界面。这一技术的关键就在于图片素材的制作,将界面大部分工作交予美工。