3.9 Qt中与界面相关的类库

Qt的核心框架是一套C++类库,里面的类很多,它们的合集就是一个大大的类库,也是一个应用程序的编程框架。有了框架,就可以往框架内添加自己的代码来实现我们所需要的Qt应用程序。这个过程好比开发商造好了整幢大楼,把毛坯房卖给了我们,而我们要做的就是装修,使之可以居住。

要成为Qt编程高手,熟悉Qt类库是必需的。Qt类库非常庞大,不能眉毛胡子一把抓,对于初学者来说,应该由浅入深。实际工作中常用到的类可组成两张继承图,如图3-13和图3-14所示。

图3-13

图3-13中的类主要涉及对话框类(QDialog)、菜单类(QMenu)、主窗口类(QMainWindow)等各个控件类,这是在Qt编程中经常会遇到的,它们的基类是QWidget。

Qt的类库很大,我们不需要(也不可能)全部记住,刚学习时只需要抓住几个头(父类,见图3-14)即可,其他虾兵蟹将(子类)在用到的时候再学习。

图3-14

3.9.1 QObject类

QObject类是所有Qt类的基类,是Qt对象模型的核心。它最主要的特征是关于对象间无缝通信的机制:信号与槽(槽就是信号处理函数,后面会讲到)。

任何对象都要实现信号与槽机制,Q_OBJECT宏是强制的。不管是否真正用到信号与槽机制,最好在所有QObject子类中都使用Q_OBJECT宏,以免出现一些不必要的错误。

所有的Qt Widgets都是基础的QObject类。如果一个对象是Widget,那么isWidgetType()函数就能判断出。

QObject类既没有复制构造函数也没有赋值操作符,实际上它们使用宏Q_DISABLE_COPY()声明为私有的。所有派生自QObject类的对象都使用这个宏声明复制构造函数和赋值操作符为私有的。

3.9.2 QWidget类

QWidget类是所有用户界面对象的基类,被称为基础窗口部件。主窗口、对话框、标签、按钮、文本输入框等都是窗口部件。这些部件可以接收用户输入,显示数据和状态信息,并且在屏幕上绘制自己。Qt把没有嵌入到其他部件的部件称为窗口,一般窗口都有边框和标题栏,就像程序中的部件(Widget)和标签(Label)一样,QMainWindow类和大量的QDialog子类是一般的窗口类型。窗口就是没有父部件的部件,所以又称为顶层部件。

3.9.3 和主窗口有关的类

主窗口就是一种顶层窗口,可以用来显示数据、图形等。程序的主窗口是经常和用户打交道的用户界面元素,它上面通常可以存放菜单栏、工具栏、停靠控件、状态栏等,每个控件都对应着类。另外,对于这些控件上的操作也提供了相应的类,比如QAction等。

(1)QMainWindow类

这个类表示主窗口本身。

(2)QDockWidget类

该类表示停靠控件。

(3)QMenu类

该类用于菜单栏、上下文菜单和其他弹出菜单的菜单控件。菜单栏通常位于主窗口上方。

(4)QToolBar类

该类提供了一个通用的工具栏部件。它可以容纳许多与操作相关的不同控件,如按钮、下拉菜单、组合框和数字显示框。通常,工具栏与菜单和键盘快捷键可以很好地协作使用。工具栏通常位于菜单栏下方。

(5)QStatusBar类

该类表示状态栏。状态栏通常位于主窗口的底部,用于显示当前程序状态信息或解释某个命令的含义。

以上是主窗口上常见的界面元素。和这些控件相关的操作也封装成了几个类。

(1)QAction类

QAction类表示和控件有关的用户界面操作。

(2)QActionGroup类

QActionGroup类用于把控件的操作进行组合。

(3)QWidgetAction类

通过接口扩展QAction类,用于将自定义控件插入到基于操作的容器(如工具栏)中。

3.9.4 对话框类和控件类

对话框是另外一种常见的顶层窗口,上面可以存放不同的控件,让用户通过控件来操作所需的功能。

(1)QDialog类

QDialog类是对话框窗口的基类,可以衍生出不少子类,比如文件对话框类、颜色对话框类、打印对话框类等。

对话框窗口主要用于短期任务和与用户进行简短的通信。对话框有两种:模态和非模态(后面我们会详细介绍它们的区别)。QDialog类可以提供返回值,并且可以有默认按钮。

(2)各个控件类

在Qt中,控件又称为小部件。控件各种各样,比如按钮控件(QAbstractButton)、编辑框控件(QTextEdit)等。后面我们将详细介绍常见控件的用法。

3.9.5 Qt Widgets应用程序类型

在项目向导中新建项目时,如果选择了Qt Widgets Application,那么最终生成的程序就是Qt Widgets应用程序,如图3-15所示。

图3-15

根据在向导中选择基类的不同,Qt Widgets程序可以分为3大类:基于主窗口的Widgets程序、基于Widgets的Widgets程序和基于对话框的Widgets程序。我们可以在Qt Creator的向导对话框中进行选择,如图3-16所示。

如果用的是VC2017,也可以在向导对话框中进行选择,如图3-17所示。

图3-16

图3-17

通过向导生成这3种类型的程序而不需要编写一行代码,不过向导生成的程序只是一个程序架构,还是需要自己手动输入具体的程序代码来实现所需的功能。

下面我们来生成这3类的Widgets程序。

【例3.11】 一个简单的主窗口程序(Qt Creator版)

(1)启动Qt Creator 4.8.2,新建一个Qt Widgets项目,项目名为test。然后跟着向导操作,直到在类信息向导对话框上选择(默认已经选中)基类为QMainWindow,如图3-18所示。

然后继续单击“下一步”按钮,直到向导完成。

图3-18

(2)向导完成后,会帮我们创建如图3-19所示的文件。

如果要设计界面,可以双击mainwindow.ui,此时将打开设计师界面,在该界面上能以可视化方式进行界面设计。main.cpp中定义了程序入口函数main()。mainwindow.cpp中定义了表示主窗口的MainWindow类,该类继承自QMainWindow。MainWindow类的对象在main函数中有定义,如下所示:

在一个窗口的Qt程序中,至少有一个应用程序对象和窗口(这里是主窗口)对象。比如:

    QApplication a(argc, argv); //定义应用程序对象
    MainWindow w; //定义一个主窗口对象

(3)不需要添加任何代码,直接按Ctrl+R快捷键运行程序,其中编译的进度状态可以在右下角状态栏上看到,如图3-20所示。

稍等片刻,运行成功,运行结果如图3-21所示。

这个主窗口上还创建了工具栏,虽然还没有具体的内容。另外,在右下角的3根斜线表示该窗口可以通过鼠标拖拉边框来进行缩放。

图3-19

图3-20

图3-21

【例3.12】 一个简单的主窗口程序(VC版)

(1)启动VC2107,新建一个Qt GUI Application项目,项目名为test。然后一路跟着向导操作,直到在可以选择基类的向导对话框上选择(默认已经选中)基类为QMainWindow。为了更加直观,把类名由默认的test改为MainWindow,如图3-22所示。然后单击Finish按钮,一个Qt程序就自动创建好了。

(2)打开解决方案资源管理器视图,VC已经帮我们创建好如图3-23所示的文件。

图3-22

图3-23

如果要设计界面,可以双击MainWindow.ui,此时将打开设计师界面,在该界面上能以可视化方式进行界面设计。main.cpp中定义了程序入口函数main()。MainWindow.cpp中定义了表示主窗口的类MainWindow,该类继承自QMainWindow。MainWindow类的对象在main()函数中有定义,如下所示:

(3)不添加任何代码,直接按Ctrl+F5快捷键运行程序,此时VC会自动在下方显示输出视图。我们可以看到编译时的状态信息,如果没有错误就会显示编译成功,如图3-24所示。

在图3-24中,显示成功1个、失败0个,说明程序运行成功了。运行结果如图3-25所示。

图3-24

图3-25

上面的例子程序是基于QMainWindow类的,下面来看一下基于QWidget类的界面程序。QWidget类是所有窗口类的父类,功能最简单。

【例3.13】 一个简单的Widget窗口程序(Qt Creator版)

(1)启动Qt Creator 4.8.2,新建一个Qt Widgets项目,项目名为test,然后一路跟着向导操作,直到在可以选择基类的向导对话框上选择基类为QWidget。为了更加直观,我们把类名由默认的test改为QWidget,如图3-26所示。

图3-26

继续单击“下一步”按钮直到完成。

(2)打开解决方案资源管理器视图,可以看到Qt Creator已经创建好如图3-27所示的文件。

如果要设计界面,可以双击widget.ui,此时将打开设计师界面,在该界面上能以可视化方式进行界面设计。main.cpp中定义了程序入口函数main()。widget.cpp中定义了表示主窗口的Widget类,该类继承自QWidget类。Widget类的对象在main()函数中有定义,如下所示:

(3)不添加任何代码,直接按Ctrl+F5快捷键运行程序,如果没有错误就会显示编译成功,运行结果如图3-28所示。

图3-27

图3-28

【例3.14】 一个简单的Widget窗口程序(VC版)

(1)启动VC2107,新建一个Qt GUI Application项目,项目名为test。然后一路跟着向导操作,直到在选择基类的向导对话框上选择基类为QWidget。为了更加直观,我们把类名由默认的test改为widget,如图3-29所示。

图3-29

然后单击Finish按钮,一个Qt程序就自动创建好了。

(2)打开解决方案资源管理器视图,可以看到VC已经创建好如图3-30所示的文件。

如果要设计界面,可以双击widget.ui,此时将打开设计师界面,在该界面上能以可视化方式进行界面设计。main.cpp中定义了程序入口函数main()。widget.cpp中定义了表示主窗口的widget类,该类继承自QWidget。widget类的对象在main函数中有定义,如下所示:

(3)不需要添加任何代码,直接按Ctrl+F5快捷键运行程序,此时VC会自动在下方显示输出视图。我们可以看到编译时的状态信息,如果没有错误就会显示编译成功,最终运行效果如图3-31所示。

还有一种程序类型是对话框程序,我们将在后面一章详细介绍。长久以来,不同的开发环境,控制台程序和窗口图形界面程序井水不犯河水,很少有交集。但在Qt中,它们的结合是那么的简单。下面我们看一个例子。

【例3.15】 控制台程序出现Widget窗口

(1)启动Qt Creator 4.8.2,新建一个控制台程序项目,项目名为test。

(2)打开main.cpp,输入如下代码:

注意,默认建立的控制台程序给出的应用程序类是QCoreApplication,但是要在控制台中使用QWidget就必须使用QApplication类。QCoreApplication类提供了一个事件循环,用于非GUI应用程序给自己提供事件循环,因此对于Qt非GUI的应用程序,应该使用QCoreApplication类。对于GUI应用程序(比如用到了Widget窗口),应该使用QApplication类。QApplication类定义在widgets模块中,与QWidget类相关,能设置鼠标双击的间隔时间、按键的间隔时间、鼠标拖曳距离和时间、滚轮滚动行数等,还能获取桌面激活的窗口、模态控件、弹跳控件等。

实例化控件窗口对象后就可以调整窗口的大小并显示出来,最后设置窗口的标题。打开test.pro,在文件开头添加“QT+=widgets”。

(3)按Ctrl+R快捷键运行这个项目,运行结果如图3-32所示。

图3-30

图3-31

图3-32