Qt Qwidget类的用法(附带实例)
QWidget 类是所有用户界面类的基类,被称为基础窗口部件。

图 1 QWidget类关系图
在上图中可以看到,QWidget 继承自 QObject 类和 QPaintDevice 类:
下面通过示例来讲解几个基本概念。
注意,这里使用 new 操作符为 label2 分配了空间,但是并没有使用 delete 进行释放,这是因为在 Qt 中销毁父对象的时候会自动销毁子对象,这里 label2 指定了 parent 为 widget,所以在执行 delete widget 代码时会自动销毁作为 widget 子对象的 label2。
运行程序,效果如下图所示:

图 2 两个窗口运行效果
窗口部件是 Qt 中建立用户界面的主要元素。像主窗口、对话框、标签,还有以后要介绍的按钮、文本输入框等都是窗口部件。这些部件可以接收用户输入,显示数据和状态信息,并且在屏幕上绘制自己。有些也可以作为一个容器来放置其他部件。
Qt 中把没有嵌入其他部件中的部件称为窗口,一般窗口都有边框和标题栏,就像程序中的 widget 和 label 一样。QMainWindow 和大量的 QDialog 子类是最一般的窗口类型。窗口是没有父部件的部件,所以又称为顶级部件(top-level widget)。
与其相对的是非窗口部件,又称为子部件(child widget)。在 Qt 中大部分部件被用作子部件,嵌入在别的窗口中,如程序中的 label2。这部分内容可以在帮助中通过 Qt Widgets 和 Window and Dialog Widgets 关键字进行查看。
QWidget 提供了自我绘制和处理用户输入等基本功能,Qt 提供的所有界面元素不是 QWidget 的子类就是与 QWidget 的子类相关联。要设计自己的窗口部件,可以继承自 QWidget 或者是它的子类。
Qt::WindowType 包括了很多类型,下面演示其中的 Qt::Dialog 和 Qt::SplashScreen,更改程序中新建对象的那两行代码如下:
窗口标志 Qt::WindowFlags 可以是多个窗口类型枚举值进行按位或操作,下面我们再次更改那两行代码:
QWidget 还有一个 setWindowState() 函数用来设置窗口的状态,其参数由 Qt::WindowStates 指定,是 Qt::WindowState 枚举类型值的按位或组合。窗口状态 Qt::WindowState 包括最大化 Qt::WindowMaximized、最小化 Qt::WindowMinimized、全屏显示 Qt::WindowFullScreen 和活动窗口 Qt::WindowActive 等,默认值为正常状态 Qt::WindowNoState。
在前面的例子中已经看到,widget 默认的大小就是它所包含的子部件 label2 的大小,而 widget 和 label 出现时在窗口上的位置也是不确定的。对于窗口的大小和位置,根据是否包含边框和标题栏两种情况,要用不同的函数来获取,如下图所示。

图 3 窗口几何布局
可以在帮助中通过 Window and Dialog Widgets 关键字查看相关内容。
这里的函数分为两类,一类是包含框架的,一类是不包含框架的:

图 1 QWidget类关系图
在上图中可以看到,QWidget 继承自 QObject 类和 QPaintDevice 类:
- QObject 类是所有支持 Qt 对象模型(Qt Object Model)的对象的基类;
- QPaintDevice 类是所有可以绘制的对象的基类。
下面通过示例来讲解几个基本概念。
QWidget窗口与子部件
打开 Qt Creator,新建 Empty qmake Project 项目,项目名称为 mywidget,完成后在 mywidget.pro 中添加“QT += widgets”。然后往项目中添加新的 C++ 源文件 main.cpp,并添加以下代码。#include <QtWidgets> int main(int argc, char *argv[]) { QApplication a(argc, argv); // 新建QWidget类对象,默认parent参数是nullptr,所以它是个窗口 QWidget *widget = new QWidget(); // 设置窗口标题 widget->setWindowTitle(QObject::tr("我是widget")); // 新建QLabel对象,默认parent参数是nullptr,所以它是个窗口 QLabel *label = new QLabel(); label->setWindowTitle(QObject::tr("我是label")); // 设置要显示的信息 label->setText(QObject::tr("label:我是个窗口")); // 改变部件大小,以便能显示出完整的内容 label->resize(180, 20); // label2指定了父窗口为widget,所以不是窗口 QLabel *label2 = new QLabel(widget); label2->setText(QObject::tr("label2:我不是独立窗口,只是widget的子部件")); label2->resize(250, 20); // 在屏幕上显示出来 label->show(); widget->show(); int ret = a.exec(); delete label; delete widget; return ret; }这里包含了头文件 #include <QtWidgets>,因为下面所有要用到的类,如 QApplication、QWidget 等都包含在 QtWidgets 模块中,为了简便,就只包含了 QtWidgets 的头文件。
程序中定义了一个 QWidget 类对象的指针 widget 和两个 QLabel 对象指针 label 与 label2,其中 label 没有父窗口,而 label2 在 widget 中,widget 是其父窗口。一般的原则是要包含尽可能少的头文件,这里直接包含了整个模块,虽然可行但并不推荐。
注意,这里使用 new 操作符为 label2 分配了空间,但是并没有使用 delete 进行释放,这是因为在 Qt 中销毁父对象的时候会自动销毁子对象,这里 label2 指定了 parent 为 widget,所以在执行 delete widget 代码时会自动销毁作为 widget 子对象的 label2。
运行程序,效果如下图所示:

图 2 两个窗口运行效果
窗口部件是 Qt 中建立用户界面的主要元素。像主窗口、对话框、标签,还有以后要介绍的按钮、文本输入框等都是窗口部件。这些部件可以接收用户输入,显示数据和状态信息,并且在屏幕上绘制自己。有些也可以作为一个容器来放置其他部件。
Qt 中把没有嵌入其他部件中的部件称为窗口,一般窗口都有边框和标题栏,就像程序中的 widget 和 label 一样。QMainWindow 和大量的 QDialog 子类是最一般的窗口类型。窗口是没有父部件的部件,所以又称为顶级部件(top-level widget)。
与其相对的是非窗口部件,又称为子部件(child widget)。在 Qt 中大部分部件被用作子部件,嵌入在别的窗口中,如程序中的 label2。这部分内容可以在帮助中通过 Qt Widgets 和 Window and Dialog Widgets 关键字进行查看。
QWidget 提供了自我绘制和处理用户输入等基本功能,Qt 提供的所有界面元素不是 QWidget 的子类就是与 QWidget 的子类相关联。要设计自己的窗口部件,可以继承自 QWidget 或者是它的子类。
QWidget窗口类型
前面讲到窗口一般都有边框和标题栏,其实这也不是必需的。QWidget 的构造函数有两个参数:- QWidget *parent = nullptr。parent 就是指父窗口部件,默认值为 nullptr,表明没有父窗口;
- Qt::WindowFlags f = Qt::WindowFlags()。f 是 Qt::WindowFlags 类型的,它是 Qt::WindowType 枚举类型值的或组合。Qt::WindowType 枚举类型用来为部件指定各种窗口系统属性,比如 f=0 表明窗口类型的值为 Qt::Widget,这是 QWidget 的默认类型,这种类型的部件如果有父窗口,那么它就是子部件,否则就是独立窗口。
Qt::WindowType 包括了很多类型,下面演示其中的 Qt::Dialog 和 Qt::SplashScreen,更改程序中新建对象的那两行代码如下:
QWidget *widget = new QWidget(nullptr, Qt::Dialog); QLabel *label = new QLabel(nullptr, Qt::SplashScreen);这时运行程序可以看到,当更改窗口类型后窗口的样式发生了改变,一个是对话框类型,另一个是欢迎窗口类型。
窗口标志 Qt::WindowFlags 可以是多个窗口类型枚举值进行按位或操作,下面我们再次更改那两行代码:
QWidget *widget = new QWidget(nullptr,Qt::Dialog | Qt::FramelessWindowHint); QLabel *label = new QLabel(nullptr,Qt::SplashScreen | Qt::WindowStaysOnTopHint);Qt::FramelessWindowHint 用来产生一个没有边框的窗口,而 Qt::WindowStaysOnTopHint 用来使该窗口停留在所有其他窗口上面。
这里只列举了两个简单的例子来演示 f 参数的使用,读者可以在帮助中通过 Qt::WindowFlags 关键字查看其他值的介绍。在 Qt 的示例程序中有一个 Window Flags 程序演示了所有窗口类型,可以直接在 Qt Creator 的欢迎模式中打开它。现在两个窗口都没有了标题栏,那么怎么关闭程序呢?其实可以通过 Alt+3 快捷键打开“应用程序输出”窗口,然后单击那个红色的按钮来强行关闭程序。
QWidget 还有一个 setWindowState() 函数用来设置窗口的状态,其参数由 Qt::WindowStates 指定,是 Qt::WindowState 枚举类型值的按位或组合。窗口状态 Qt::WindowState 包括最大化 Qt::WindowMaximized、最小化 Qt::WindowMinimized、全屏显示 Qt::WindowFullScreen 和活动窗口 Qt::WindowActive 等,默认值为正常状态 Qt::WindowNoState。
QWidget窗口几何布局
对于一个窗口,往往要设置它的大小和运行时出现的位置,这就涉及窗口的几何布局。在前面的例子中已经看到,widget 默认的大小就是它所包含的子部件 label2 的大小,而 widget 和 label 出现时在窗口上的位置也是不确定的。对于窗口的大小和位置,根据是否包含边框和标题栏两种情况,要用不同的函数来获取,如下图所示。

图 3 窗口几何布局
可以在帮助中通过 Window and Dialog Widgets 关键字查看相关内容。
这里的函数分为两类,一类是包含框架的,一类是不包含框架的:
- 包含框架:x()、y()、frameGeometry()、pos() 和 move() 等函数;
- 不包含框架:geometry()、width()、height()、rect() 和 size() 等函数。