基础窗口部件 QWidget
QWidget 类是所有用户界面对象的基类,因此被称为基础窗口部件。QWidget 继承自 QObject 类和QPaintDevice 类,其中 QObject 类是所有支持 Qt 对象模型(Qt Object Model)的对象的基类,QPaintDevice 类是所有可以绘制的对象的基类。
QWidget 提供了自我绘制和处理用户输入等基本功能,Qt 提供的所有界面元素不是 QWidget 的子类就是与 QWidget 的子类相关联。要设计自己的窗口部件,可以继承自 QWidget 或者它的子类。
窗口与子部件
窗口与子部件(Widgets)是构建用户界面的基本构建块。
Qt 中把没有嵌入到其他部件中的部件称为窗口,一般窗口都有边框和标题栏。**窗口就是没有父部件的部件,所以又称为顶级部件(top-level widget)。与其相对的是非窗口部件,又称为子部件(child widget)。**在 Qt 中大部分部件被用作子部件,嵌入在别的窗口中,如下面程序中的 label 标签。
举个例子:
#include <QApplication>
#include <QWidget>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 新建 QWidget 窗口
QWidget widget;
widget.resize(400, 300);
QLabel label(&widget);
label.setWindowTitle(QObject::tr("我是 label"));
label.setText(QObject::tr("label:我不是独立窗口,只是 widget 的子部件"));
QLabel label2;
label2.setWindowTitle(QObject::tr("我是 label2"));
label2.setText(QObject::tr("label2:我是个窗口"));
label2.resize(400, 300);
label2.show();
widget.show();
return a.exec();
}
运行结果如图所示:
不难看出,widget 与 label2 都是窗口,label 是 widget 的子部件。
窗口类型
上节说过窗口一般都有边框和标题栏,其实我们也可以将边框和标题栏去掉。QWidget 的构造函数如下:
explicit QWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
参数 parent:父窗口部件(默认为 nullptr,表明没有父窗口)
参数 f:窗口类型(Qt::WindowFlags 类型,WindowType 类型太多,在此不一一列举,只选择 Qt::Dialog 和 Qt::SplashScreen)
将上节代码修改成:
#include <QApplication>
#include <QWidget>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 新建 QWidget 窗口
QWidget widget(nullptr, Qt::Dialog); // 使用 Dialog 类型
widget.resize(400, 300);
QLabel label(&widget);
label.setWindowTitle(QObject::tr("我是 label"));
label.setText(QObject::tr("label:我不是独立窗口,只是 widget 的子部件"));
QLabel label2(nullptr, Qt::SplashScreen); // 使用 SplashScreen 类型(启动画面)
label2.setWindowTitle(QObject::tr("我是 label2"));
label2.setText(QObject::tr("label2:我是个窗口"));
label2.resize(400, 300);
label2.show();
widget.show();
return a.exec();
}
运行结果如图所示:
可以看到,更改窗口类型后窗口的样式发生了改变,一个是对话框类型,一个是启动画面类型。
窗口几何布局
对于一个窗口,往往要设置它的大小和运行时出现的位置。
窗口的几何布局图:
这里的函数分为两类,一类是包含框架的,一类是不含框架的:
- 包含框架:x()、y()、frameGeometry()、pos()和move()等函数
- 不包含框架:geometry()、width()、height()、rect()和size()等函数
其实,我们上面的代码已经设置了 widget 和 lebel2 的大小(800 * 600)。接着我们改变一下 label 在 widget 内的位置:
QLabel label(&widget);
label.setWindowTitle(QObject::tr("我是 label"));
label.setText(QObject::tr("label:我不是独立窗口,只是 widget 的子部件"));
label.move(30, 80); // 添加位置设置
运行结果如图所示: