Qt 提供的默认基类只有 QMainWindow、QWidget 和 QDialog 这 3 种。QMainWindow 是带有菜单栏和工具栏的主窗口类,QDialog 是各种对话框的基类,而它们全部继承自 QWidget。不仅如此,其实所有的窗口部件都继承自 QWidget,如下图所示。这里只讲解 QWidge、QDialog 和其他一些常用部件类。
一、基础窗口部件 QWidget
QWidget 类是所有用户界面对象的基类,被称为基础窗口部件。在上图中可以看到,QWidget 继承自 QObject 类和 QPaintDevice 类,其中 QObject 类是所有支持 Qt 对象模型(Qt Object Model)的基类,QPaimDevice 类是所有可以绘制的对象的基类。 这里先讲解 Qt 窗口部件的概念和窗口类型。
1.1 窗口与窗口部件
先来看一个例子。打开 QtCreator,新建空的 Qt 项目,项目名称为 myWidget1。然后往项目中添加 C++ 源文件 “main.cpp”,并添加以下代码:
#include <QApplication>
#include <QDialog>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication a(argc,argv);
// 新建QWidget对象,默认parent参数是nullptr,所以它无父窗口,不是窗口部件,而是个窗口
// Qt::Dialog: Indicates that the widget is a window that should be decorated as a dialog.
QWidget *widget = new QWidget(nullptr,Qt::Dialog);
//设置窗口标题
widget->setWindowTitle(QObject::tr("我是widget"));
// 新建QLabel对象,默认parent参数是nullptr,所以它无父窗口,是个窗口
QLabel *label = new QLabel(nullptr,Qt::SplashScreen);
label->setWindowTitle(QObject::tr("我是label"));
// 设置要显示的信息
label->setText(QObject::tr("label:我是个窗口"));
// 改变窗口部件大小,以便能显示出完整的内容
label->resize(300,40);
// label2指定了父窗口为widget,所以是widget的窗口部件,而不是窗口
QLabel *label2 = new QLabel(widget);
label2->setText(QObject::tr("label2:我不是独立窗口,只是widget的子部件"));
label2->resize(300,20);
// 在屏幕上显示出来
label->show();
widget->show();
// 事件循环
int ret = a.exec();
// 结束时间循环后,释放申请的内存
delete label;
delete widget;
return ret;
}
程序中定义了一个 QWidget 类对象的指针 widget 和两个 QLabel 对象指针 labe1 与 label2 ,其中 labe1 没有父窗口,而 label2 在 widget 中, widget 是其父窗口。然后运行程序,效果如下图所示。
窗口部件(Widget):这里简称部件,是 Qt 中建立用户界面的主要元素。像主窗口、对话框、标签、还有以后要介绍到的按钮、文本输人框等都是窗口部件。
Qt 中把没有嵌入到其他部件中的部件称为窗口,一般窗口都有边框和标题栏,就像程序中的 widget 和 label —样。QMainWindow 和大量的 QDialog 子类是最一般的窗口类型。窗口就是没有父部件的部件,所以又称为顶级部件。与其相对的是非窗口部件,又称为子部件。
1.2 窗口几何布局
对于一个窗口,往往要设置它的大小和运行时出现的位置,这就是本小节要说的窗口几何布局。对于窗口的大小和位置,根据是否包含边框和标题栏两种情况,要用不同的函数来获取。可以在帮助索引中查看 Window and Dialog Widgets 关键字,文档中显示了窗口的几何布局图,如下图所示。
这里的函数分为两类,一类是包含框架的,另一类是不包含框架的:
- 包含框架:x()、y()、frameGeometry()、pos()和 move() 等函数;
- 不包含框架:geometry()、width()、height()、rect() 和 size() 等函数。
x()、y() 分别返回部件的位置坐标的 x、y 值,它们的默认值为 0。而 geometry() 和 frameGeometry() 函数分别返回没有边框和包含边框的窗口框架矩形的值,其返回值是 QRect 类型的,就是一个矩形,它的形式是(x, y, 宽, 髙)。
二、其他窗口部件
2.1 QFrame 类族
QFrame 类是带有边框的部件的基类,它的子类有最为常用的标签部件 QLabel,另外还有 QLCDNumber、QSplitter、QStackedWidget、QToolBox 和 QAbstractScrollArea 类。QAbstractScrollArea 类是所有带有滚动区域的部件类的抽象基类,这里需要说明,在 Qt 中凡是带有 Abstract 字样的类都是抽象基类。对于抽象基类,我们是不能直接使用的,但是可以继承该类实现自己的类,或者使用它提供的子类。QAbstractScrollArea 的子类中有最常用的文本编辑器类 QTextEdit 类和各种项目视图类。
带边框部件最主要的特点就是可以有一个明显的边界框架。QFrame 类的主要功能也就是用来实现不同的边框效果,这主要是由边框形状(Shape)和边框阴影(Shadow)组合来形成的。 QFrame 类中定义的主要边框形状如下图1和图2所示。其中,lineWidth 是边框边界的线的宽度;而 midLineWidth 是在边框中额外插入的一条线的宽度,作用是形成 3D 效果,并且只在 Box、Hline 和 VLine 表现为凸起或者凹陷时有用。
因为下面要讲的部件都是 QFrame 类的子类,也都是 Qt 的标准部件,所以大多会在 Qt 设计器中直接设置其属性。能在属性栏中设置的属性,其类中就一定有相关的函数可以使用代码来实现, 只要根据名字在类的参考文档中查找就可以了。
(1)QLabel
标签 QLabel 部件用来显示文本或者图片。在设计器中往界面拖人一个 Label,然后将其拖大,并在属性栏中设置其对齐方式为 alignment 属性,水平的改为 AlignHCenter,垂直的改为AlignVCenter,这样 QLabel 中的文本就会显示在正中间。属性栏中还有一个 wordwrap,选中它就可以实现文本的自动换行。下面看一下怎么在标签中使用图片。首先在 mywidget. cpp 文件中添加头文件 #include <QPixmap>,然后在 MyWidget 类的构造函数中添加一行代码:
ui->label->setPixmap(QPixmap("F:/logo.png"));
这样就可以在标签中显示 F 盘中的 “logo, png” 图片了。显示图片时使用了图片的绝对路径 “F:/logo. png”,这样需要指明盘符,也可以使用相对路径。最好的方法是使用资源管理器,将图片放到程序中。在 QLabel 中还可以显示 gif 动态图片,在 mywidget. cpp 中添加头文件 #include <QMovie>,然后在 myWidget 的构造函数中继续添加代码:
QMovie *movie = new QMovie("F:/donghua.gif");
ui->label->setMovie(movie);
movie->start();
(2)QLCDNumber
QLCDNumber 部件可以让数码显示与液晶数字一样的效果。在 QLCDNumber 中可以显示的数码有0/O、1、2、3、4、5/S、6、7、8、9/g、负号、A、B、C、D、E、F、h、H、L、O、P、r、u、U、Y 、冒号、度符号(输入时使用单引号来代替)和空格。
(3)QStackedWidget
QStackedWidget 类提供了一个部件栈,可以有多个界面(称为页面),每个界面可以拥有自己的部件,不过每次只能显示一个界面。对于这个部件,需要使用 QComboBox 或者 QListWidget 来选择它的各个页面。
在设计模式中向界面拖入一个 ListWidget 和一个 Stacked Widget。 在 List Widget 上右击 ,选择“编辑项目 ”菜单,然后在编辑列表窗口部件对话框中按下左下角的加号添加两项,并更改名称为“第一页”和“第二页”。然后在 Stacked Widget 上拖一个 Label,更改文本为“第一页”,然后再单击 Stacked Widget 右上角的小箭头进人下一页,再拖人一个标签,更改文本为“第二页”, 然后再将 Stacked Widget 部件的 frameShape 属性更改为 StyledPanel 。
最后在信号和槽设计模式,将 HstWidget 部件的 currentRowChanged() 信号和 stackedWidget 的 setCurrent 槽关联。设置完成后运行程序,效果如下图所示。可以看到,现在可以单击 listWidget 中的项目来选择 stackedWidget 的页面了。也可以在设计模式中在 stackedWidget 上右击来添加新的页面。
(4)QToolBox
QToolBox类提供了一列层叠窗口部件,就像最常用聊天工具QQ中的抽屉效果。从部件栏中选择Tool Box拖入到我们界面上。在上面右击,选择“插人页→在当前页之后”菜单项来新插入一页。然后更改其 frameShape 属性为 Box,并分别单击各个页的标签,更改其 curremltemText 分别为 “好友”,“黑名单” 和 “陌生人”。然后运行程序,效果如下图所示。
2.2 按钮部件
QAbstractButton 类是按钮部件的抽象基类,提供了按钮的通用功能。它的子类包括复选框 QCheckBox、标准按钮QPushButton、单选框按钮QRadioButton 和工具按钮 QToolButton。关于这一节,可以参考欢迎中的示例程序 Group Box Example,它在 Widgets 分类中。
(1)QPushButton
QPushButton 部件提供了 一个标准按钮。将按钮的显示文本设置为英文字母,在首字母前添加"&"符号,那么就可以将这个按钮的快捷键设置为 Alt 加上这个字母。其它更多的功能可以查看帮助文档,这里由于篇幅问题就不再介绍了。
(2)QCheckBox、QRadioButton和QGroupBox
对于调查表之类的应用,往往提供多个选项供选择。有些是可以选择多项的,有些只能选择其中一项。复选框 QCheckBox 类提供了同时选择多项的功能,而 QRadioBimon 提供了只能选择一项的功能,一般要把一组按钮放到一个 QGroupBox 中来进行管理。其它更多的功能可以查看帮助文档,这里由于篇幅问题就不再介绍了。
2.3 行编辑器
行编辑器QLineEdit部件是一个单行的文本编辑器,允许用户输人和编辑单行的纯文本内容,而且提供了一系列有用的功能,包括撤销与恢复、剪切和拖放等操作。其中剪切笈制等功能是行编辑自带的,不用自己编码实现。一些具体功能,可以査看Qt欢迎中的示例程序 Line Edits,它在 Widgets 分类中,这里由于篇幅问题就不再介绍了。
2.4 数值设定框
QAbstractSpinBox 类是一个抽象基类,提供了一个数值设定框和一个行编辑器来显示设定值。它有3个子类 QDateTimeEdit、QSpinBox 和 QDoubleSpinBox 分别用来完成日期时间、整数和浮点数的设定。关于这一小节,可以查看 Widgets 分类下的 Spin Boxes 示例程序,这里由于篇幅问题就不再介绍了。
2.5 滑块部件
QAbstractSlider 类提供了一个区间内的整数值,有一个滑块,可以定位到一个整数区间的任意值。这个类是一个抽象基类,有3个子类 QScrollBar、QSlider 和 QDial。 其中,滚动条 QScrollBar 更多用在 QScrollArea 类中来实现滚动区域;而 QSlider 是最常见的音量控制或多媒体播放进度等滑块;QDial 是一个刻度表盘。关于这些部件,可以参考 Widgets 分类下的 Sliders 示例程序,这里由于篇幅问题就不再介绍了。