下面我们以一个实例来讲解样式表的应用。这个例子取材于Qt Demo,比较复杂,有一定难度,基本上覆盖了前面几章讲述的各种技能点,主要包括:
◆ 如何自定义Qt 的样式表
◆ 如何在应用程序中应用样式表
◆ 如何不使用样式表来设置应用程序的样式
◆ 如何使用单继承法从.ui文件创建派生类
◆ 如何自定义资源集文件
◆ 如何使信号和槽自动连接
◆ 如何在两个窗口之间建立关联
◆ 元对象系统方法的使用
这个程序名字叫stylesheet,其运行后的效果如图9-17所示。
图9-17 实例运行效果
该例子基于主窗口样式,有些类似于我们在网上所常见的填写个人资料的网站注册程序。
程序有两个主菜单,依次点击【File】->【Edit Style】菜单项,将弹出如图9-18所示的设置样式表的对话框,在其中内置了几种样式供选择,使用者也可以在编辑框中输入自定义的样式。设置完成后,主界面的窗口部件的样式将依此相应的变化。里面的Coffee样式自定义了push button、frames和tooltip,但使用了下层的风格 (例如这里是Windows XP风格)来绘制checkbox,combobox和radio button。Pagefold风格完全重新定义了对话框中使用的所有控件的外观,从而实现了一种独特的,平台无关的外观。
图9-18 样式表编辑器
这个程序里面包含如下原生源文件:
◆ mainwindow.ui
◆ stylesheeteditor.ui
◆ stylesheet.qrc
◆ /qss/coffee.qss
◆ /qss/default.qss
◆ /qss/pagefold.qss
◆ /images/*.png
◆ mainwindow.h
◆ mainwindow.cpp
◆ stylesheeteditor.h
◆ stylesheeteditor.cpp
其中,mainwindow.ui和stylesheeteditor.ui分别是主程序和样式编辑器的界面布局文件,是使用Qt Designer制作的。Stylesheet.qrc是资源集文件,在其中描述了程序中用到的样式表文件和图片文件的位置和名称。在qss文件夹中包含了3个.qss文件,它们描述了程序中用到的样式,我们的程序将读取它们并转换成样式表。在images文件夹中放置了程序中用到的图片文件。mainwindow.h和mainwindow.cpp构成了程序中的主程序类,而stylesheeteditor.h和stylesheeteditor.cpp构成了样式编辑器类。
下面我们就结合源代码为大家讲解这个程序的功能是怎样实现的。
首先看看mainwindow.h
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3 #include <QtGui>
4 #include "ui_mainwindow.h"
5 class StyleSheetEditor;
6 class MainWindow : public QMainWindow
{
7 Q_OBJECT
8 public:
9 MainWindow();
10 private slots:
11 void on_editStyleAction_triggered();
12 void on_aboutAction_triggered();
13 private:
14 StyleSheetEditor *styleSheetEditor;
15 Ui::MainWindow ui;
};
16 #endif
第1、2和第16行一起构成了头文件的预定义卫哨,这样做的目的是为了防止程序中重复定义或包含头文件,是严谨的编程风格,建议大家遵循这一范例的做法。
第3行引入QtGui模块的声明,它包含了QMainWindow类的定义。
第4行引入ui_mainwindow.h的声明。
第5行采用前置声明的方式引入样式编辑器类StyleSheetEditor。
第6行声明主程序类MainWindow单公有继承自QMainWindow类。
第7行时必需的,因为要用到Qt的核心机制,如信号/槽机制等。
第8、9行声明MainWindow类的构造函数。
第10-12行声明私有槽,它们的命名遵循了Qt信号/槽的“自动关联规则”。
第13-15行声明了私有成员,它们分别是样式编辑器类的对象和主程序界面类的对象。从这里也可以看出,我们对.ui文件的引入将采用单继承的方式。
下面再来看一下mainwindow.cpp文件的内容。
1 #include "mainwindow.h"
2 #include "stylesheeteditor.h"
3 MainWindow::MainWindow()
{
4 ui.setupUi(this);
5 ui.nameLabel->setProperty("class", "mandatory QLabel");
6 styleSheetEditor = new StyleSheetEditor(this);
7 statusBar()->addWidget(new QLabel(tr("Ready")));
8 connect(ui.exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
9 connect(ui.aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
10 void MainWindow::on_editStyleAction_triggered()
{
11 styleSheetEditor->show();
12 styleSheetEditor->activateWindow();
}
13 void MainWindow::on_aboutAction_triggered()
{
14 QMessageBox::about(this, tr("About Style sheet"),
tr("The <b>Style Sheet</b> example shows how widgets can be styled "
"using <a href=/"http://doc.trolltech.com/4.5/stylesheet.html/">Qt "