C++ QT(二)

Qt 控件

老子曾说:“天下难事,必做于易;天下大事,必做于细”。再复杂的项目,都是由一个个小小的部分组成,只有掌握了Qt 的基本,遇到大项目也不用担心了!从这章开始我们开始学习Qt 的窗口部件,其中每种类型的窗口部件都选取一个作为例子讲解它们的用法,通过例子大家能举一反三。本章也是纯代码编程,不使用Qt Designer 图形界面开发程序。笔者认为纯代码编程的代码容易让人看懂,在Qt Designer 里设计就显得没有过多逻辑可言。在这章里我们可以学习常用的控件初始化方法,设置窗体的大小位置,颜色,文本,设计创意的例子快速学习各类控件的使用方法,力求把例子写的实用,代码注释详细。因为控件非常多,如果觉得学习控件枯燥,可以等用到这个控件(部件)时再参考,不必要一次性全部掌握,这章节的目的是了解Qt 控件类型及使用方法。
值得留意的小节是7.1.3 小节,该小节讲解如何添加资源图片和qss 文件。后面的例程都可以参考7.1.3 小节添加资源图片,不再重复写这种添加步骤。

第7.8 和7.9 小节,我们在嵌入式里经常用于处理数据,建立模型,应该花多点时间学习这两个小节。

按钮

在Qt 里,最常用使用的控件就是按钮了,有了按钮,我们就可以点击,从而响应事件,达到人机交互的效果。不管是嵌入式或者PC 端,界面交互,少不了按钮。
Qt 按钮部件是一种常用的部件之一,Qt 内置了六种按钮部件如下:
在这里插入图片描述
(1)QPushButton:下压按钮
(2)QToolButton:工具按钮
(3)QRadioButton:选择按钮
(4)QCheckBox:检查框
(5)QCommandLinkButton:命令链接按钮
(6)QDialogButtonBox:对话框按钮
这六种按钮部件作用简介如下:
QPushButton 继承QAbstractButton 类,被QCommandLinkButton 继承。通常用于执行命令或触发事件。
QToolButton 继承QAbstractButton 类。是一种用于命令或者选项的可以快速访问的按钮,通常在ToolBar 里面。工具按钮通常显示的是图标,而不是文本标签。ToolButton 支持自动浮起。在自动浮起模式中,按钮只有在鼠标指向它的时候才绘制三维的框架。
QRadioButton 继承QAbstractButton 类。RadioButton 单选按钮(单选框)通常成组出现,用于提供两个或多个互斥选项。
QCheckBox 继承QAbstractButton。复选按钮(复选框)与RadioButton 的区别是选择模式,单选按钮提供多选一,复选按钮提供多选多。
QCommandLinkButton 控件中文名是“命令链接按钮”。QCommandLinkButton 继承QPushButton。QCommandLinkButton 控件和RadioButton 相似,都是用于在互斥选项中选择一项。表面上同平面按钮一样,但是CommandLinkButton 除带有正常的按钮上的文字描述文本外,默认情况下,它也将携带一个箭头图标,表明按下按钮将打开另一个窗口或页面。
QDialogButtonBox 按钮盒子(按钮框),是由QDialogButtonBox 类包装成的。
QDialogButtonBox 继承QWidget。常用于对话框里自定义按钮,比如“确定”和“取消”按钮。
上面说的六种按钮的可用属性,信号和槽,需要用到时可在Qt 帮助文档里查看。这里我们就略过介绍它们可用属性和信号与槽了。下面我们通过例子讲解每种按钮是如何使用,一起探究它们究竟能实现什么效果。

QPushButton

控件简介

在第四章里我们就已经接触过QPushButton 了,在Qt Designer 里连接信号与槽,从而实现了关闭程序的功能。下面开始重新用编写程序的方法实现使用QPushButton 连接信号和槽实现一个小例子。

用法示例

例04_qpushbutton 窗口换肤(难度:简单),通过单击不同的按钮,改变窗口的颜色。
新建一个项目名称为为04_qpushbutton,在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。如果还不会新建一个项目,建议回到3.6 小节查看如何新建一个项目。
完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 /* 引入QPushButton类*/
6 # include < QPushButton >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明一个QPushButton对象pushButton1 */
	18 QPushButton * pushButton1;
	19      /* 声明一个QPushButton对象pushButton2 */
	20 QPushButton * pushButton2;
	21
	22 private slots:
	23      /* 声明对象pushButton1的槽函数*/
	24 void pushButton1_Clicked();


	25      /* 声明对象pushButton2的槽函数*/
	26 void pushButton2_Clicked();


	27
};
28 # endif      /* MAINWINDOW_H */

第6 行,引入QPushButton 类。
第18 和20 行,声明两个QPushButton 的对象。
第24 和26 行,声明两个QPushButton 对象的槽函数。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置宽高为800×480,位置在0, 0。(0, 0)代表原点,Qt默认最左上角的点为原
点*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化两个按钮对象,并设置其显示文本为窗口皮肤1和窗口皮肤2 */
10 pushButton1 = new QPushButton("窗口皮肤1", this);
11 pushButton2 = new QPushButton("窗口皮肤2", this);
12
13 /* 设定两个QPushButton对象的位置*/
14 pushButton1->setGeometry(300,200,80,40);
15 pushButton2->setGeometry(400,200,80,40);
16
17 /* 信号槽连接*/
18 connect(pushButton1, SIGNAL(clicked()), this,
SLOT(pushButton1_Clicked()));
19 connect(pushButton2, SIGNAL(clicked()), this,
SLOT(pushButton2_Clicked()));
20 }
21
22 MainWindow::~MainWindow()
23 {
24 }
25
26 /* 槽函数的实现*/
27 void MainWindow::pushButton1_Clicked()
28 {
29 /* 设置主窗口的样式1 */
30 this->setStyleSheet("QMainWindow { background-color: rgba(255, 245,
238, 100%); }");
31 }
32
33 /* 槽函数的实现*/
34 void MainWindow::pushButton2_Clicked()
35 {
36 /* 设置主窗口的样式2 */
37 this->setStyleSheet("QMainWindow { background-color: rgba(238, 122,
233, 100%); }");
38 }

第7 行,设置程序窗口的显示位置和显示大小,如果不设置,运行的程序窗口在Ubuntu里有可能在某个位置出现,而在Windows 一般出现在中间。
第10 和11 行,实际化QPushButton 对象。在初始化的时候可以传入QString 类型串,作为按钮的显示文本。
第14 行,设置按钮的大小和位置,按钮的大小不能设置过小,否则按钮上的文本可能显示不全。
第18 行和19 行,连接两个QPushButton 对象的信号与槽。
第27 行至38 行,两个QPushButton 的槽函数实现,设置主窗体的样式表,其中设置background-color 的rgba 参数即可改变窗体的背景颜色。关于什么是样式表,如何设置样式表,以后会以一个小节专门讲解。
在源文件“main.cpp”具体代码如下,由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译及运行后,点击窗口皮肤1 按钮,主窗体显示效果如下。
在这里插入图片描述

点击窗口皮肤2 按钮,主窗体显示效果如下。
在这里插入图片描述

QToolButton

控件简介

工具按钮(QToolButton)区别于普通按钮(QPushButton)的一点是,工具按钮(QToolButton)可以带图标。这里区别下图标和按钮的背景图片是不一样的。通常我们在QToolBar 这种工具条(工具栏)上设置不同的按钮,如果这些按钮还带图标和文本,那么QToolButton 是个不错的选择。

用法示例

例05_qtoolbutton 自定义工具栏(难度:简单)。
新建一个项目名称为05_qtoolbutton。在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5       /* 引入QToolButton类*/
6 # include < QToolButton >
7       /* 引入QToolBar类*/
8 # include < QToolBar >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19      /* 声明一个QToolButton对象*/
	20 QToolButton * toolButton;
	21      /* 声明一个QToolBar对象*/
	22 QToolBar * toolBar;
	23
};
24 # endif      /* MAINWINDOW_H */

第20 和22 行,声明QToolButton 对象和QtoolBar 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QApplication >
3 # include < QStyle >
4
5 MainWindow::MainWindow( QWidget *parent )
6 : QMainWindow( parent )
	7
{
	8       /* 设置主窗体的位置和大小*/
	9 this->setGeometry( 0, 0, 800, 480 );
	10
	11      /* 实例化QToolBar对象*/
	12 toolBar = new QToolBar( this );
	13      /* 设置toolBar的位置和大小*/
	14 toolBar->setGeometry( 0, 0, 800, 100 );
	15
	16      /* 实例化QStyle类对象,用于设置风格,调用系统类自带的图标*/
	17 QStyle * style = QApplication::style();
	18
	19      /* 使用Qt自带的标准图标,可以在帮助文档里搜索QStyle::StandardPixmap */
	20 QIcon icon =
		style->standardIcon( QStyle::SP_TitleBarContextHelpButton );
	21
	22      /* 实例化QToolButton对象*/
	23 toolButton = new QToolButton();
	24
	25      /* 设置图标*/
	26 toolButton->setIcon( icon );
	27      /* 设置要显示的文本*/
	28 toolButton->setText( "帮助" );
	29      /* 调用setToolButtonStyle()方法,设置toolButoon的样式,设置为文本置于
	         * 图标下方*/
	30 toolButton->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
	31
	32      /* 最后将toolButton添加到ToolBar里*/
	33 toolBar->addWidget( toolButton );
	34
}


35
36 MainWindow::~MainWindow()
37
{
	38
}



这段代码的流程是,初始化toolBar(工具条/工具栏)对象,然后初始化toolButton(工具按钮)对象,设置工具按钮的样式。最后将toolButton(工具按钮)添加到toolBar(工具条/工具栏)上。这样就完成了自定义工具栏的设计。
在源文件“main.cpp”具体代码如下,由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

最终程序实现的效果如下。成功的将自定义的工具按钮嵌入工具栏中。在许多含有工具栏的软件都可以看到这种设计,都可以使用Qt 来实现类似的功能。
在这里插入图片描述

QRadioButton

控件简介

QRadioButton 部件提供了一个带有文本标签的单选框(单选按钮)。
QRadioButton 是一个可以切换选中(checked)或未选中(unchecked)状态的选项按钮。
单选框通常呈现给用户一个“多选一”的选择。也就是说,在一组单选框中,一次只能选中一个单选框。默认在同一个父对象下,初始化后点击它们是互斥状态。

用法示例

例06_radiobutton 仿手机开关效果(难度:中等)。本例将实现手机开关效果,需要使用到Qt 样式表,加载qss 样式表文件,与7.1.1 小节类似,只是把样式表写到qss 文件里了。这里我们慢慢接触Qt 的样式表了,正因为有样式表我们才能写一些比较有实际应用的例子和比较炫的例子。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述

添加资源文件,按如下步骤。右键项目,选择Add New…。
在这里插入图片描述
选择一个模板,选择Qt 模板,再选择Qt Resource Files,点击Choose。这里Qt 模板我们就不详细说了,日后我们需要使用什么模板,用到再了解。现在没必要一下子各个模板的用法,实际上我们常用的不多。
在这里插入图片描述
填上资源文件的名称(可随意写一个,笔者简写为res),默认添加项目路径下。后面的步骤默认即可,点击完成。
在这里插入图片描述
新建完成了资源文件后,默认会进入res.qrc 文件编辑模式(如果关闭了,可以右键这个文件点击选择“Open in Editor”),点击Add Prefix 添加前缀,添加前缀的目的是方便分类管理文件,比如我们现在第⑪处添加了前缀/。“/”一定需要写,否则会找不到路径,这有点像Linux的根节点一样。
在这里插入图片描述
添加了前缀后,我们添加资源图片,放在/images 前缀的下面。这里我们准备了两张图片,在本项目路径images 文件夹(images 文件夹先手动创建)下。如下图步骤,添加完成需要按“Ctrl + S”保存res.qrc 才会看到左边的结果。添加完成如下图。
在这里插入图片描述
添加qss 文件。QSS 文件是使用Qt 程序相关联的样式表文件。它由GUI 元素的外观和感觉,包括布局,颜色,鼠标的行为,大小和字体。它的风格,一个可以合并到一个UI(用户界面)。与HTML 的CSS 类似,Qt 的样式表是纯文本的格式定义,在应用程序运行时可以载入和解析这些样式定义,从而使应用程序的界面呈现不同的效果。
在这里插入图片描述
新建一个style.qss 文件,如下图,默认添加到项目的路径下,后面步骤默认即可,直至完成。
在这里插入图片描述
qss 文件添加后如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 /* 引入QRadioButton */
6 #include <QRadioButton>
7
8 class MainWindow : public QMainWindow
9 {
10 Q_OBJECT
11
12 public:
13 MainWindow(QWidget *parent = nullptr);
14 ~MainWindow();
15
16 private:
17 /* 声明两个QRadioButton对象*/
18 QRadioButton *radioButton1;
19 QRadioButton *radioButton2;
20 };
21 #endif // MAINWINDOW_H

在第18 和19 行声明两个QRadioButton对象。
在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 主窗体设置位置和显示的大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8 this->setStyleSheet( "QMainWindow {background-color: rgba(200, 50,
100, 100%);}" );
	9
	10      /* 实例化对象*/
	11 radioButton1 = new QRadioButton( this );
	12 radioButton2 = new QRadioButton( this );
	13
	14      /* 设置两个QRadioButton的位置和显示大小*/
	15 radioButton1->setGeometry( 300, 200, 100, 50 );
	16 radioButton2->setGeometry( 400, 200, 100, 50 );
	17
	18      /* 设置两个QRadioButton的显示文本*/
	19 radioButton1->setText( "开关一" );
	20 radioButton2->setText( "开关二" );
	21
	22      /* 设置初始状态,radioButton1的Checked为false,另一个为true*/
	23 radioButton1->setChecked( false );
	24 radioButton2->setChecked( true );
	25
}


26
27 MainWindow::~MainWindow()
28
{
	29
}



第23 行和24 行,设置QRadioButton对象的初始化状态,让它们互斥。
在源文件“main.cpp”具体代码如下。我们需要在main.cpp 里加载qss 文件。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4                       /* 引入QFile */
5 # include < QFile >
6
7 int main( int argc, char *argv[] )
8
{
	9 QApplication a( argc, argv );
	10              /* 指定文件*/
	11 QFile file( ":/style.qss" );
	12
	13              /* 判断文件是否存在*/
	14 if ( file.exists() )
	{
		15      /* 以只读的方式打开*/
		16 file.open( QFile::ReadOnly );
		17      /* 以字符串的方式保存读出的结果*/
		18 QString styleSheet = QLatin1String( file.readAll() );
		19      /* 设置全局样式*/
		20 qApp->setStyleSheet( styleSheet );
		21      /* 关闭文件*/
		22 file.close();
		23
	}
	24 MainWindow w;
	25 w.show();
	26 return(a.exec() );
	27
}



第11 行至23 行,读取style.qss 的内容。并设置全局样式。
在源文件“style.qss”具体代码如下,与HTML 里的css 语法相似。如果不会写qss 的内容,可以参考Qt 帮助文档的内容,在里面搜索“qt style”。在里面找相关的例子参考,这里我们只是初步了解下这个qt style。

1 QRadioButton {
	2 spacing	: 2px;
	3 color		: white;
	4
}
5 QRadioButton::indicator {
	6 width		: 45px;
	7 height	: 30px;
	8
}
9 QRadioButton::indicator : unchecked {
	10 image : url( : / images / switch_off.png );
	11
}
12 QRadioButton::indicator : checked {
	13 image : url( : / images / switch_on.png );
	14
}

在第10 行和第13 行,设置QRadioButton 的indicator 的背景图片。这样当它们点击切换时就会看到类似开关切换的效果了。

运行效果

编译程序运行的效果如下。点击关闭开关一,开关二即打开;点击开关二,开关一即打开。
因为它们默认是互斥的效果。在某种情况下我们需要使用这种效果,比如我们在网上看视频时经常需要切换线路,线路可能有几种,但是只有一种是激活状态的,我们就可以应用到这个方向上。
在这里插入图片描述

在这个例子里我们学习到如何添加资源,步骤也详细,后面的例程都可参考这个例程来添加资源文件,不再详细讲解添加过程。我们已经初步了解了Qt 的样式表文件,如果要做好看的界面Qt 的样式表文件是少不了的。可能我们还不懂Qt 样式表的语法,不知道如何下手。我们可以边学边了解,可以参考Qt 帮助文档里的用法,qss 的功能不止这么点。现在的重点是学习QRadioButton 这个控件。

QCheckBox

控件简介

QCheckBox 继承QAbstractButton。复选按钮(复选框)与RadioButton 的区别是选择模式,单选按钮提供多选一,复选按钮提供多选多。

用法示例

例07_qcheckbox,三态选择框(难度:简单)。使用一个QCheckBox,用户通过点击可改变当选择框的状态。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。笔者已经添加了qss 文件和三张资源图片。如果还不会添加qss 文件和资源图片,请参考7.1.3 小节。

在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 /* 引入QCheckBox */
6 # include < QCheckBox >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明一个QCheckBox对象*/
	18 QCheckBox * checkBox;
	19 private slots:
	20      /* 声明QCheckBox的槽函数,并带参数传递,用这个参数接收信号的参数*/
	21 void checkBoxStateChanged( int );


	22
	23
};
24 # endif      /* MAINWINDOW_H */

在第18 和19 行声明两个QCheckBox 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 主窗体设置位置和显示的大小及背景颜色*/
7 this->setGeometry(0, 0, 800, 480);
8 this->setStyleSheet("QMainWindow {background-color: rgba(100, 100,
100, 100%);}");
9
10 /* 实例化对象*/
11 checkBox = new QCheckBox(this);
12
13 /* 设置QCheckBox位置和显示大小*/
14 checkBox->setGeometry(350, 200, 250, 50);
15
16 /* 初始化三态复选框的状态为Checked */
17 checkBox->setCheckState(Qt::Checked);
18
19 /* 设置显示的文本*/
20 checkBox->setText("初始化为Checked状态");
21
22 /* 开启三态模式,必须开启,否则只有两种状态,即Checked和Unchecked */
23 checkBox->setTristate();
24
25 /* 连接checkBox的信号stateChanged(int),与我们定义的槽
checkBoxStateChanged(int)连接*/
26 connect(checkBox, SIGNAL(stateChanged(int)), this,
SLOT(checkBoxStateChanged(int)));
27 }
28
29 MainWindow::~MainWindow()
30 {
31 }
32
33 /* 槽函数的实现*/
34 void MainWindow::checkBoxStateChanged(int state)
35 {
36 /* 判断checkBox的state状态,设置checkBox的文本*/
37 switch (state) {
38 case Qt::Checked:
39 /* 选中状态*/
40 checkBox->setText("Checked状态");
41 break;
42 case Qt::Unchecked:
43 /* 未选中状态*/
44 checkBox->setText("Unchecked状态");
45 break;
46 case Qt::PartiallyChecked:
47 /* 半选状态*/
48 checkBox->setText("PartiallyChecked状态");
49 break;
50 default:
51 break;
52 }
53 }

第23 行,需要注意的是设置QCheckBox 对象checkBox 需要设置为三态模式。
在源文件“main.cpp”具体代码如下。我们需要在main.cpp 里加载qss 文件。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4                       /* 引入QFile */
5 # include < QFile >
6
7 int main( int argc, char *argv[] )
8
{
	9 QApplication a( argc, argv );
	10              /* 指定文件*/
	11 QFile file( ":/style.qss" );
	12
	13              /* 判断文件是否存在*/
	14 if ( file.exists() )
	{
		15      /* 以只读的方式打开*/
		16 file.open( QFile::ReadOnly );
		17      /* 以字符串的方式保存读出的结果*/
		18 QString styleSheet = QLatin1String( file.readAll() );
		19      /* 设置全局样式*/
		20 qApp->setStyleSheet( styleSheet );
		21      /* 关闭文件*/
		22 file.close();
		23
	}
	24 MainWindow w;
	25 w.show();
	26 return(a.exec() );
	27
}



第11 行至23 行,读取style.qss 的内容。并设置全局样式。
在源文件“style.qss”具体代码如下。

1 QCheckBox{
2 spacing: 5px;
3 color: white;
4 }
5 QCheckBox::indicator {
6 width: 50px;
7 height: 50px;
8 }
9 QCheckBox::indicator:enabled:unchecked {
10 image: url(:/images/unchecked.png);
11 }
12 QCheckBox::indicator:enabled:checked {
13 image: url(:/images/checked.png);
14 }
15 QCheckBox::indicator:enabled:indeterminate {
16 image: url(:/images/indeterminate.png);
17 }

在第10 行和第13 行,设置QCheckBox 的indicator 的背景图片。这样当它们点击切换时就会看到QCheckBox 的三种选择状态了。

运行效果

编译程序运行的效果如下,多次点击checkBox,即可看到QCheckBox 的三种状态切换。
选中状态时。
在这里插入图片描述
半选状态。
在这里插入图片描述
未选中状态。
在这里插入图片描述
我们经常在软件安装时可以看到这种三态选择框,如果我们设计的程序有多种选择的项也可以设计这种选择框。

QCommandLinkButton

控件简介

QCommandLinkButton 控件中文名是“命令链接按钮”。QCommandLinkButton 继承QPushButton。CommandLinkButton 控件和RadioButton 相似,都是用于在互斥选项中选择一项。
表面上同平面按钮一样,但是CommandLinkButton 除带有正常的按钮上的文字描述文本外,默认情况下,它也将携带一个箭头图标,表明按下按钮将打开另一个窗口或页面。

用法示例

例08_qcommandlinkbutton 链接窗口(难度:简单)。使用一个QCommandLinkButton,点击打开系统的窗口。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 /* 引入QCommandLinkButton */
6 # include < QCommandLinkButton >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明一个QCommandLinkButton对象*/
	18 QCommandLinkButton * commandLinkButton;
	19
	20 private slots:
	21      /* 声明槽函数,用于点击commandLinkButton后触发*/
	22 void commandLinkButtonClicked();


	23
	24
	25
};
26 # endif /* MAINWINDOW_H */

在第18 行,声明一个QCommandLinkButton 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 /* 引入桌面服务,用来打开系统文件夹对话框*/
3 #include <QDesktopServices>
4 /* 引入QUrl */
5 #include <QUrl>
6
7 MainWindow::MainWindow(QWidget *parent)
8 : QMainWindow(parent)
9 {
10 /* 主窗体设置位置和显示的大小*/
11 this->setGeometry(0, 0, 800, 480);
12
13 /* 实例化对象*/
14 commandLinkButton = new QCommandLinkButton(
15 "打开/home目录", "点击此将调用系统的窗口打开/home目录",this);
16
17 /* 设置QCommandLinkButton位置和显示大小*/
18 commandLinkButton->setGeometry(300, 200, 250, 60);
19
20 /* 信号槽连接*/
21 connect(commandLinkButton, SIGNAL(clicked()), this,
22 SLOT(commandLinkButtonClicked()));
23 }
24
25 MainWindow::~MainWindow()
26 {
27 }
28
29 void MainWindow::commandLinkButtonClicked()
30 {
31 /* 调用系统服务打开/home目录*/
32 QDesktopServices::openUrl(QUrl("file:home/") );
33 }

第14 行,实例化时原型是QCommandLinkButton::QCommandLinkButton(const QString &text,const QString &description, QWidget *parent = nullptr)。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下。
点击中间的打开/home 目录按钮,结果如下。系统弹出一个窗口,直接打开到/home 目录。
在这里插入图片描述
点击打开/home 目录后,系统将弹出/home 目录路径窗口。
在这里插入图片描述

QDialogButtonBox

控件简介

对话框和消息框通常以符合该平台界面指导原则的布局呈现按钮。不同平台的对话框总是有不同的布局。QDialogButtonBox 允许开发人员向其添加按钮,并将自动使用适合用户桌面环境的布局。也就是说我们可以使用系统的自带的对话框按钮,也可以自己定义对话框按钮。
QDialogButtonBox 常用的按钮有如下几种,更多的可以参考Qt 帮助文档。
在这里插入图片描述

用法示例

例09_qdialogbuttonbox,自定义QDialogButtonBox 里的按钮(难度:简单)。使用一个QDialogButtonBox,在QDialogButtonBox 添加Qt 提供的按钮,或者自定义按钮。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5       /* 引入QDialogButtonBox */
6 # include < QDialogButtonBox >
7       /* 引入QPuhsButton */
8 # include < QPushButton >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19      /* 声明一个QDialogButtonBox对象*/
	20 QDialogButtonBox * dialogButtonBox;
	21
	22      /* 声明一个QPushButton对象*/
	23 QPushButton * pushButton;
	24
	25 private slots:
	26      /* 声明信号槽,带QAbstractButton *参数,用于判断点击了哪个按钮*/
	27 void dialogButtonBoxClicked( QAbstractButton * );


	28
	29
};
30 # endif      /* MAINWINDOW_H */

第18 行,声明一个QDialogButtonBox 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 /* 引入QDebug */
3 #include <QDebug>
4
5 MainWindow::MainWindow(QWidget *parent)
6 : QMainWindow(parent)
7 {
8 /* 主窗体设置位置和显示的大小*/
9 this->setGeometry(0, 0, 800, 480);
10
11 /* 实例化并设置按钮的盒子的大小和位置*/
12 dialogButtonBox = new QDialogButtonBox(this);
13 dialogButtonBox->setGeometry(300, 200, 200, 30);
14
15 /*使用Qt的Cancel按钮*/
16 dialogButtonBox->addButton(QDialogButtonBox::Cancel);
17
18 /*将英文"Cancel"按钮设置为中文"取消" */
19 dialogButtonBox->button(QDialogButtonBox::Cancel)->setText("取消
");
20
21 /* 设定位置与大小*/
22 pushButton = new QPushButton(tr("自定义"));
23
24 /* 将pushButton添加到dialogButtonBox,并设定ButtonRole为ActionRole
*/
25 dialogButtonBox->addButton(pushButton,
QDialogButtonBox::ActionRole);
26
27 /* 信号槽连接,带参数QAbstractButton *,用于判断用户点击哪个按键*/
28 connect(dialogButtonBox, SIGNAL(clicked(QAbstractButton * )),
29 this, SLOT(dialogButtonBoxClicked(QAbstractButton *)));
30 }
31
32 MainWindow::~MainWindow()
33 {
34 }
35
36 void MainWindow::dialogButtonBoxClicked(QAbstractButton *button)
37 {
38 /* 判断点击的对象是否为QDialogButtonBox::Cancel */
39 if(button == dialogButtonBox->button(QDialogButtonBox::Cancel)) {
40 /* 打印“单击了取消键” */
41 qDebug() <<"单击了取消键"<<endl;
42 /* 判断点击的对象是否为pushButton */
43 }else if(button == pushButton) {
44 /* 打印“单击了自定义键” */
45 qDebug() <<"单击了自定义键"<<endl;
46 }
47 }

第16 行,实例化时原型是void QDialogButtonBox::addButton(QAbstractButton *button,
QDialogButtonBox::ButtonRole role)。
第41 和45 行,我们第一次用qDebug()。Qt 一般调试都是用qDebug()来打印的。这与C++的cout 是功能基本一样。只是Qt 自定义为qDebug()而已。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下。点击自定义按钮和取消按钮,在应用程序输出窗口可以看到对应的点击事件。
在这里插入图片描述

输入窗口部件

Qt Designer 窗口部件提供的面板中,提供了16 种输入部件如下
在这里插入图片描述
(1)Comb Box:组合框
(2)Font Comb Box:字体组合框
(3)Line Edit:单行编辑框
(4)Text Edit:文本编辑框
(5)Plain Text Edit:纯文本编辑框
(6)Spin Box:数字旋转框
(7)Double Spin Box:双精度数字旋转框
(8)Time Edit:时间编辑框
(9)Date Edit:日期编辑框
(10)Date/Time Edit:日期时间编辑框
(11)Dial:数字拨盘框
(12)Horizontal Scroll Bar:水平滚动条
(13)Vertical Scroll Bar:垂直滚动条
(14)Horizontal Slider:水平滑动条
(15)Vertical Slider:垂直滑动条
(16)Key sequence Edit:按键序列编辑框
这十六种按钮部件作用简介如下:
QComboBox 继承QWidget 类,被QFontComboBox 类继承。通常用于用户显示选项列表的方法,这种方法占用最少的屏幕空间。
QFontComboBox 继承QComboBox。QFontComboBox 小部件是一个允许用户选择字体系列的组合框。组合框中填充了按字母顺序排列的字体家族名称列表。FontComboBox 常用于工具栏,与ComboBox 一起用于控制字体大小,并与两个ToolButtons 一起用于粗体和斜体。
QLineEdit 继承QWidget。QLineEdit 小部件是一个单行文本编辑器。行编辑允许用户使用一组有用的编辑函数输入和编辑一行纯文本,包括撤消和重做、剪切和粘贴以及拖放。通过更改行编辑的echoMode(),它还可以用作“只写”字段,用于输入如密码等。
QTextEdit 继承QAbstractScrollArea,被QTextBrowser 继承。QTextEdit 是一个高级所见即所得查看器/编辑器,支持使用html 样式的标记进行rich text 格式化。它经过优化以处理大型文档并快速响应用户输入。QTextEdit 用于段落和字符。段落是格式化的字符串,它被字包装以适应小部件的宽度。在阅读纯文本时,默认情况下,一个换行表示一个段落。一份文件由零个或多个段落组成。段落中的文字与段落的对齐方式一致。段落之间用硬换行符隔开。段落中的每个字符都有自己的属性,例如字体和颜色。QTextEdit 可以显示图像,列表和表格。如果文本太大而无法在文本编辑的视图中查看,视图中则会出现滚动条。
QPlainTextEdit 是一个支持纯文本的高级查看器/编辑器。它被优化为处理大型文档和快速响应用户输入。
QSpinBox 继承QAbstractSpinBox。用于处理整数和离散值(例如:月份名称)而QDoubl eSpinBox 则用于处理浮点值。他们之间的区别就是处理数据的类型不同,其他功能都基本相同。
QSpinBox 允许用户通过单击上/下按钮或按下键盘上的上/下按钮来选择一个值,以增加/减少当前显示的值。用户还可以手动输入值。

QDoubleSpinBox 继承QAbstractSpinBox。QDoubleSpinBox 则用于处理浮点值。QDoubleS pinBox 允许用户通过单击“向上”和“向下”按钮或按下键盘上的“向上”或“向下”按钮来选择当前显示的值。用户还可以手动输入值。
QTimeEdit 继承QDateTimeEdit。QTimeEdit 用于编辑时间,而QDateEdit 用于编辑日期。
QDateEdit 继承QDateTimeEdit。QDateEdit 用于编辑日期,而QTimeEdit 用于编辑时间。
QDateTimeEdit 类提供了一个用于编辑日期和时间的小部件。QDateTimeEdit 允许用户使用键盘或箭头键编辑日期,以增加或减少日期和时间值。箭头键可用于在QDateTimeEdit 框中从一个区域移动到另一个区域。
QDial 类提供了一个圆形范围控制(如速度计或电位器)。QDial 用于当用户需要在可编程定义的范围内控制一个值,并且该范围要么是环绕的(例如,从0 到359 度测量的角度),要么对话框布局需要一个正方形小部件。由于QDial 从QAbstractSlider 继承,因此拨号的行为与滑块类似。当wrapping()为false(默认设置)时,滑块和刻度盘之间没有真正的区别。它们共享相同的信号,插槽和成员功能。您使用哪一个取决于您的用户期望和应用程序类型。
QScrollBar 继承QAbstractSlider。QScrollBar 小部件提供垂直或水平滚动条,允许用户访问比用于显示文档的小部件大的文档部分。它提供了用户在文档中的当前位置和可见文档数量的可视化指示。滚动条通常配有其他控件,可以实现更精确的导航。
QSlider 继承QAbstractSlider。QSlider 类提供垂直或水平滑动条小部件,滑动条是用于控制有界值的典型小部件。它允许用户沿着水平或垂直凹槽移动滑块手柄,并将手柄的位置转换为合法范围内的整数值。
QKeySequenceEdit 继承QWidget。这个小部件允许用户选择QKeySequence, QKeySequence通常用作快捷方式。当小部件接收到焦点并在用户释放最后一个键后一秒结束时,将启动记录,通常用作记录快捷键。

QComboBox

控件简介

QComboBox 类提供了Qt 下拉组合框的组件。

用法示例

例10_qcombobox,选择省份(难度:简单),通过点击下拉按钮的项,选择其中一项,然后打印出当前选择项的内容。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 /* 引入QComboBox */
6 # include < QComboBox >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明一个QComboBox对象*/
	18 QComboBox * comboBox;
	19
	20 private slots:
	21      /* 声明QComboBox对象的槽函数*/
	22 void comboBoxIndexChanged( int );


	23
	24
};
25 # endif      /* MAINWINDOW_H */

第20 行,声明一个QComboBox 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 /* 引入QDebug */
3 #include <QDebug>
4
5 MainWindow::MainWindow(QWidget *parent)
6 : QMainWindow(parent)
7 {
8 /* 设置主窗体的显示位置与大小*/
9 this->setGeometry(0, 0, 800, 480);
10
11 /* 实例化对象*/
12 comboBox = new QComboBox(this);
13
14 /* 设置comboBox的显示位置与大小*/
15 comboBox->setGeometry(300, 200, 150, 30);
16
17 /* 添加项,我们添加三个省份,作为comboBox的三个选项*/
18 comboBox->addItem("广东(默认)");
19 comboBox->addItem("湖南");
20 comboBox->addItem("四川");
21
22 /* 信号槽连接*/
23 connect(comboBox, SIGNAL(currentIndexChanged(int)), this,
24 SLOT(comboBoxIndexChanged(int)));
25 }
26
27 MainWindow::~MainWindow()
28 {
29 }
30
31 void MainWindow::comboBoxIndexChanged(int index)
32 {
33 /* 打印出选择的省份*/
34 qDebug()<<"您选择的省份是"<< comboBox->itemText(index)<<endl;
35 }

第18 至20 行,添加Item,也就是项。
第30 至34 行,当点击下拉列表改变选择的省份就会触发currentIndexChanged(int)这个信号,就会相应打印项的省份名称。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,当点击下拉选择框选择省份时,槽函数将打印出您选择的省份。
在这里插入图片描述

点击选择“湖南”,则打印出“您选择的省份是湖南”。
在这里插入图片描述
QComboBox 我们常会在一些需要下拉列表选择的项目中用到。比如QQ 登录如果有多个帐号选择就需要这个QComboBox。

QFontComboBox

控件简介

QFontComboBox 类提供了下拉选择字体系列的组合框小部件。

用法示例

例11_qfontcombobox,字体选择(难度:简单),通过点击下拉按钮的项,选择其中一项,然后打印出当前选择项的内容。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5       /* 引入QFontComboBox */
6 # include < QFontComboBox >
7       /* 引入QLable */
8 # include < QLabel >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19      /* 声明一个QFontComboBox对象*/
	20 QFontComboBox * fontComboBox;
	21      /* 声明一个Label对象,用于显示当前字体变化*/
	22 QLabel * label;
	23
	24 private slots:
	25      /* 声明QFontComboBox对象使用的槽函数*/
	26 void fontComboBoxFontChanged( QFont );
	27
	28
};
29 # endif      /* MAINWINDOW_H */

第20 行,声明一个QFontComboBox 对象。
在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置主窗体的显示位置和大小*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化对象*/
10 fontComboBox = new QFontComboBox(this);
11 label = new QLabel(this);
12
13 /* 设置显示的位置与大小*/
14 fontComboBox->setGeometry(280, 200, 200, 30);
15 label->setGeometry(280, 250, 300, 50);
16
17 /* 信号与槽连接*/
18 connect(fontComboBox, SIGNAL(currentFontChanged(QFont)), this,
19 SLOT(fontComboBoxFontChanged(QFont)));
20 }
21
22 MainWindow::~MainWindow()
23 {
24 }
25
26 /* 槽函数实现*/
27 void MainWindow::fontComboBoxFontChanged(QFont font)
28 {
29 /* 将label里的文本内容设置为所选择的字体*/
30 label->setFont(font);
31
32 /* 定义一个字符串接收当前项的字体*/
33 QString str = "用此标签显示字体效果\n设置的字体为:" +
34 fontComboBox->itemText(fontComboBox->currentIndex());
35
36 /* 将字符串的内容作为label的显示内容*/
37 label->setText(str);
38 }

第27 至37 行,当选择的字体改变时,槽函数就会设置label 的字体,并打印当前字体的名称。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,当点击FontCOmboBox 字体组合框选择字体后,Label 标签显示的字体将改变为当前所选择的字体。(注意Ubuntu 与Windows 的字体不一样,所以显示的效果有可能不一样,下图为Ubuntu 的字体显示效果)
在这里插入图片描述
在手机,电脑一些软件都有设置字体的功能,由用户自行选择,所以我们这个QFontComboBox 就可以应用于此种场合。当然也有设置字体的大小,颜色等,这些由我们自由设计。

QLineEdit

控件简介

QLineEdit 小部件是一个单行文本编辑器。行编辑允许用户使用一组有用的编辑函数输入和编辑一行纯文本。包括撤消和重做、剪切和粘贴以及拖放。通过更改行编辑的echoMode(),它还可以用作“只写”字段,用于输入如密码等。

用法示例

例12_qlineedit,单行输入框(难度:简单),通过点击下拉按钮的项,选择其中一项,然后打印出当前选择项的内容。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。像引入头文件,设置主窗体大小位置和实例化对象这种注释我们慢慢淡化,不再写详细注释了。读者看了前面的对这种设置已经很清楚了。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QLineEdit >
6 # include < QPushButton >
7 # include < QLabel >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16 private:
	17      /* 声明一个QLineEdit对象*/
	18 QLineEdit * lineEdit;
	19
	20      /* 声明一个QPushButton对象*/
	21 QPushButton * pushButton;
	22
	23      /* 声明一个QLabel对象*/
	24 QLabel * label;
	25
	26 private slots:
	27      /* 声明一个槽函数,响应pushButton的clicked事件*/
	28 void pushButtonClicked();


	29
};
30 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 this->setGeometry(0, 0, 800, 480);
7
8 lineEdit = new QLineEdit(this);
9 lineEdit->setGeometry(280, 200, 200, 20);
10
11 pushButton = new QPushButton(this);
12 pushButton->setGeometry(500, 200, 50, 20);
13 pushButton->setText("确认");
14
15 label = new QLabel(this);
16 label->setGeometry(280, 250, 400, 20);
17 label->setText("您输入的内容是:");
18
19 /* 信号槽连接*/
20 connect(pushButton,SIGNAL(clicked()), this,
21 SLOT(pushButtonClicked()));
22 }
23
24 MainWindow::~MainWindow()
25 {
26 }
27
28 void MainWindow::pushButtonClicked()
29 {
30 /* 字符串变量str */
31 QString str;
32
33 str = "您输入的内容是:";
34 str += lineEdit->text();
35
36 /* 设置label里的文本显示内容*/
37 label->setText(str);
38 /* 在点击了确认键之后清空lineEdit单行输入框*/
39 lineEdit->clear();
40 }

第28 至40 行,当我们在单选输入框里输入完成后,将输入的内容设置为在label 的文本内容。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,当在QLineEdit 单行输入框内输入文本内容后,单击QPushButton确认按钮后,QLabel 的文本内容将显示您所输入的内容。然后QLineEdit 将清空,可再次输入。
在这里插入图片描述
QLineEdit 的简单使用如上,笔者也是简单的介绍了它的用法。要想写好一点的例子,需要我们主动思考,比如,做个将这个QLineEdit 应用到密码登录窗口上,输入密码,然后判断这个密码是否与预设的密码一样才解锁等。

QTextEdit

控件简介

QTextEdit 类提供了一个查看器/编辑器小部件。

用法示例

例13_qtextedit 文本编辑框(难度:简单),用一个QTextEdit 来演示文本的输入,用两个QPushButton 来模拟文本编辑的全选与清除。在QTextEdit 里也可用键盘的快捷键(如Ctrl+A)来完成全选,复制,粘贴等操作。Qt 提供了全选,复制粘贴等这一类的函数方便用户操作,下面用简单的实例来演示。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3 # include < QTextEdit >
4 # include < QPushButton >
5
6 # include < QMainWindow >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明一个QTextEdit对象*/
	18 QTextEdit * textEdit;
	19
	20      /* 声明两个QPushButton对象*/
	21 QPushButton * pushButtonSelectAll;
	22 QPushButton * pushButtonClearAll;
	23
	24 private slots:
	25      /* 声明两个槽函数,响应按钮点击响应的事件*/
	26 void pushButtonSelectAllClicked();


	27 void pushButtonClearAllClicked();


	28
	29
};
30 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置主窗体显示的位置和大小*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例和对象,设置位置和显示大小*/
10 textEdit = new QTextEdit(this);
11 textEdit->setGeometry(0, 0, 800, 400);
12
13 /* 实例和对象,设置位置和显示大小,设置文本*/
14 pushButtonSelectAll = new QPushButton(this);
15 pushButtonSelectAll->setGeometry(200, 420, 50, 20);
16 pushButtonSelectAll->setText("全选");
17
18 /* 实例和对象,设置位置和显示大小,设置文本*/
19 pushButtonClearAll = new QPushButton(this);
20 pushButtonClearAll->setGeometry(500, 420, 50, 20);
21 pushButtonClearAll->setText("清除");
22
23 /* 信号槽连接*/
24 connect(pushButtonSelectAll, SIGNAL(clicked()), this,
25 SLOT(pushButtonSelectAllClicked()));
26 connect(pushButtonClearAll, SIGNAL(clicked()), this,
27 SLOT(pushButtonClearAllClicked()));
28
29 }
30
31 MainWindow::~MainWindow()
32 {
33 }
34
35 void MainWindow::pushButtonSelectAllClicked()
36 {
37 /* 设置焦点为textEdit */
38 textEdit->setFocus();
39 /* 判断文本编辑框内容是否为空,不为空则全选*/
40 if(!textEdit->toPlainText().isEmpty()){
41 /* 全选*/
42 textEdit->selectAll();
43 }
44 }
45
46 void MainWindow::pushButtonClearAllClicked()
47 {
48 /* 清空textEdit里的文本内容*/
49 textEdit->clear();
50 }
51

第35 至49 行,当我们在文本输入框里输入完成后,当点击全选按钮后,需要设置焦点到textEdit 上,否则将不能设置全选。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,在编辑框里输入文字后,点击按钮全选,点击清除则清除编辑框内的全部内容。如下图为点击全选的效果。
在这里插入图片描述

QPlainTextEdit

控件简介

QPlainTextEdit 类提供了一个用于编辑和显示纯文本的小部件,常用于显示多行文本或简单文本。

用法示例

例14_qplaintextedit 文本浏览编辑器(难度:简单),用一个QPlainTextEdit 来读取本当前工程里的一个文件,并用一个RadioButton 里将QPlainTextEdit 设为只读。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QPlainTextEdit >
5 # include < QRadioButton >
6
7 # include < QMainWindow >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 声明对象*/
	19 QPlainTextEdit * plainTextEdit;
	20 QRadioButton * radioButton;
	21
	22 private slots:
	23      /* 槽函数*/
	24 void radioButtonClicked();


	25
	26
};
27 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 #include <QDir>
3 #include <QTextStream>
4 #include <QCoreApplication>
5
6 MainWindow::MainWindow(QWidget *parent)
7 : QMainWindow(parent)
8 {
9 /* 设置当前程序的工作目录为可执行程序的工作目录*/
10 QDir::setCurrent(QCoreApplication::applicationDirPath());
11
12 this->setGeometry(0, 0, 800, 480);
13
14 plainTextEdit = new QPlainTextEdit(this);
15 plainTextEdit->setGeometry(0, 50, 800, 430);
16
17 radioButton = new QRadioButton(this);
18 radioButton->setGeometry(650, 20, 100, 20);
19 radioButton->setText("只读模式");
20
21 /* 打开可执行程序目录里的moc_mainwindow.cpp,注意如果是Windows下
22 moc_mainwindow.cpp并不在当前目录,而在上一级目录"../moc_mainwindow.cpp
"*/
23 QFile file("moc_mainwindow.cpp");
24
25 /* 以只读模式打开,但是可以在plainTextEdit里编辑*/
26 file.open((QFile::ReadOnly | QFile::Text));
27
28 /* 加载到文件流*/
29 QTextStream in(&file);
30
31 /* 从文本流中读取全部*/
32 plainTextEdit->insertPlainText(in.readAll());
33
34 /* 信号槽连接*/
35 connect(radioButton, SIGNAL(clicked()), this,
36 SLOT(radioButtonClicked()));
37
38 }
39
40 MainWindow::~MainWindow()
41 {
42 }
43
44 void MainWindow::radioButtonClicked()
45 {
46 /* 检查radioButton是否选中*/
47 if(radioButton->isChecked()) {
48 /* 设置为只读模式*/
49 plainTextEdit->setReadOnly(true);
50 } else {
51 /* 设置为非只读模式*/
52 plainTextEdit->setReadOnly(false);
53 }
54 }

第44 和54 行,检查radioButton 是否选中。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,当程序正常运行后会打开程序当前路径下的”moc_mainwindow.cpp” 文件,(注意在Windows 下moc_mainwindow.cpp 应该写成”…/moc_mainwindow.cpp”),且在QPlainTextEdit 编辑框下是可编辑的,当选中程序界面上的只读
模式时,QPlainTextEdit 编辑框就不可以再编辑。相反可以取消只读模式则可以再编辑。
在这里插入图片描述
有了QTextEdit,为什么还有QPlainTextEdit?QPlainTextEdit 可以理解为QTextEdit 的低配版。QPlainTextEdit 支持纯文本显示,QTextEdit 支持富文本(支持多种格式,比如插入图片,链接等)显示。就是多一个样式。QPlainTextEdit 显示的效率比QTextEdit 高,如果需要显示大量文字,尤其是需要滚动条来回滚动的时候,QPlainTextEdit 要好很多。

QSpinBox

控件简介

QSpinBox 类提供了一个微调框小部件。

用法示例

例15_qspinbox 窗口背景不透明调节器(难度:简单),用一个QSpinBox 来调节程序窗体的整体不透明度。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSpinBox>
class MainWindow : public QMainWindow
{
	Q_OBJECT
public:
	MainWindow( QWidget *parent = nullptr );
	~MainWindow();
private:
/* 声明一个QSpinBox对象*/
	QSpinBox *spinBox;
private slots:
/* 槽函数*/
	void spinBoxValueChanged( int );
};
#endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 this->setGeometry(0, 0, 800, 480);
7
8 /* 设置主窗口背景颜色,rgb颜色标准,a代表不透明度(0~100)*/
9 this->setStyleSheet("QMainWindow{background-color: "
10 "rgba(100, 100, 100, 100%) }");
11
12 spinBox = new QSpinBox(this);
13 spinBox->setGeometry(350, 200, 150, 30);
14
15 /* 设置范围0~100 */
16 spinBox->setRange(0, 100);
17
18 /* 设置步长为10 */
19 spinBox->setSingleStep(10);
20
21 /* 设置初始值为100 */
22 spinBox->setValue(100);
23
24 /* 设置后缀*/
25 spinBox->setSuffix("%不透明度");
26
27 /* 信号槽连接*/
28 connect(spinBox,SIGNAL(valueChanged(int)), this,
29 SLOT(spinBoxValueChanged(int)));
30 }
31
32 MainWindow::~MainWindow()
33 {
34 }
35
36 void MainWindow::spinBoxValueChanged(int opacity)
37 {
38 /* 转换为double数据类型*/
39 double dobleopacity = (double)opacity / 100;
40
41 /* 设置窗体不透明度,范围是0.0~1.0。1则为不透明,0为全透明*/
42 this->setWindowOpacity(dobleopacity);
43 }

第42 行,设置主窗体的不透明度。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,程序初始化界面时是全不透明,不透明度值为100%,当点击向下调节SpinBox 后,整个窗体的不透明将会变小。当不透明度的值变小时,窗口将透明化。
在这里插入图片描述

QDoubleSpinBox

控件简介

QDoubleSpinBox 类提供了一个用于处理浮点值微调框小部件。与QSpinBox 作用基本一样,与QSpinBox 不同的是,QDoubleSpinBox 类处理的是浮点值数据。

用法示例

例16_qdoublespinbox 窗口大小调节器(难度:简单),用一个QDoubleSpinBox 来调节程序窗口的整体大小。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QDoubleSpinBox >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* 声明一个QDoubleSpinBox对象*/
	17 QDoubleSpinBox * doubleSpinBox;
	18
	19 private slots:
	20      /* 槽函数*/
	21 void doubleSpinBoxValueChanged( double );


	22
	23
};
24 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 this->setGeometry(0, 0, 800, 480);
7
8 /* 实例化和设置显示的位置与大小*/
9 doubleSpinBox = new QDoubleSpinBox(this);
10 doubleSpinBox->setGeometry((this->width() - 200) / 2,
11 (this->height() - 30) / 2,
12 200, 30);
13 /* 设置前缀*/
14 doubleSpinBox->setPrefix("窗口大小");
15
16 /* 设置后缀*/
17 doubleSpinBox->setSuffix("%");
18
19 /* 设置范围*/
20 doubleSpinBox->setRange(50.00, 100.00);
21
22 /* 设置初始值*/
23 doubleSpinBox->setValue(100.00);
24
25 /* 设置步长*/
26 doubleSpinBox->setSingleStep(0.1);
27
28 /* 信号槽连接*/
29 connect(doubleSpinBox, SIGNAL(valueChanged(double)),
30 SLOT(doubleSpinBoxValueChanged(double)));
31
32 }
33
34 MainWindow::~MainWindow()
35 {
36 }
37
38 void MainWindow::doubleSpinBoxValueChanged(double value)
39 {
40 /* 重新计算窗口的宽与高*/
41 int w = 800 * value / 100;
42 int h = 480 * value / 100;
43
44 /* 重新设置窗口的宽与高*/
45 this->setGeometry(0, 0, w, h);
46
47 /* 重新设置doubleSpinBox的显示位置*/
48 doubleSpinBox->setGeometry((this->width() - 200) / 2,
49 (this->height() - 30) / 2,
50 200, 30);
51
52 }

第35 至49 行,重新设置主窗体的宽高和doubleSpinBox 的显示位置。
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果

程序编译运行的结果如下,程序初始化界面窗口大小值为100%,当点击向下调节QDoubleSpinBox 时,整个窗体将按QDoubleSpinBox 里数值的比例缩小,最小为50.00%,相反当点击向上调节QDoubleSpinBox 时,窗口大小将整体变大,最大为100.00%。
在这里插入图片描述

QTimeEdit

7.2.8.1 控件简介
QTimeEdit 类提供一个基于QDateTimeEdit 类编辑时间的小部件。例在7.2.10 小节。

QDateEdit

7.2.9.1 控件简介
QDateEdit 类提供一个基于QDateTimeEdit 类编辑时间的小部件。例在7.2.10 小节。
7.2.10 QDateTimeEdit
7.2.10.1 控件简介
从名字可知QDateTimeEdit 类提供了一个用于编辑日期和时间的小部件。QDateTimeEdit允许用户使用键盘或箭头键编辑日期,以增加或减少日期和时间值。箭头键可用于在QDateTimeEdit 框中从一个区域移动到另一个区域。实际上是QDateTimeEdit 和QDateEdit 的组合。
7.2.10.2 用法示例
例17_qdatetimeedit 时间日期展示(难度简单),使用一个QDateTimeEdit,一个QTimeEdit以及一个QDateEdit,传入当前系统时间与日期,展示简单的日期时间控件使用方法。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QDateTimeEdit >
6 # include < QTimeEdit >
7 # include < QDateEdit >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 声明对象*/
	19 QDateTimeEdit * dateTimeEdit;
	20 QTimeEdit * timeEdit;
	21 QDateEdit * dateEdit;
	22
};
23 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9       /*实例化对象,传入当前日期与时间*/
	10 dateTimeEdit = new QDateTimeEdit(
		QDateTime::currentDateTime(), this );
	11 dateTimeEdit->setGeometry( 300, 200, 200, 30 );
	12      /* 弹出日期控件与否*/
	13      /* dateTimeEdit->setCalendarPopup(true); */
	14
	15      /* 实例化对象,传入当前时间*/
	16 timeEdit = new QTimeEdit( QTime::currentTime(), this );
	17 timeEdit->setGeometry( 300, 240, 200, 30 );
	18
	19      /* 实例化对象,传入当前日期*/
	20 dateEdit = new QDateEdit( QDate::currentDate(), this );
	21 dateEdit->setGeometry( 300, 280, 200, 30 );
	22
}


23
24 MainWindow::~MainWindow()
25
{
	26
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,当程序初始化时,分别显示系统当前的时间与日期(注意,windows 下Qt 程序显示的格式可能不一样,下图为linux 下的Qt 程序日期显示格式)。
在这里插入图片描述

QDial

7.2.11.1 控件简介
QDial 类提供了一个圆形范围控制(如速度计或电位器)。QDial 用于当用户需要在可编程定义的范围内控制一个值,并且该范围要么是环绕的(例如,从0 到359 度测量的角度),要么对话框布局需要一个正方形小部件。由于QDial 从QAbstractSlider 继承,因此拨号的行为与滑块类似。当wrapping()为false(默认设置)时,滑块和刻度盘之间没有真正的区别。它们共享相同的信号,插槽和成员功能。您使用哪一个取决于您的用户期望和应用程序类型。
7.2.11.2 用法示例
例18_qdial 车速表(难度:简单),使用一个QDial,以一个QLabel,演示QDial 的用法。
当程序初始化界面后,拖动滑块的位置,label 则会显示dial 的值。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述

在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QDial >
5 # include < QLabel >
6 # include < QMainWindow >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明对象*/
	18 QDial * dial;
	19 QLabel * label;
	20
	21 private slots:
	22      /* 槽函数*/
	23 void dialValueChanged( int );


	24
	25
};
26 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置主窗体的位置与大小*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化对象和设置显示位置与大小*/
10 dial = new QDial(this);
11 dial->setGeometry(300, 100, 200, 200);
12
13 /* 设置页长(两个最大刻度的间距)*/
14 dial->setPageStep(10);
15
16 /* 设置刻度可见*/
17 dial->setNotchesVisible(true);
18
19 /* 设置两个凹槽之间的目标像素数*/
20 dial->setNotchTarget(1.00);
21
22 /* 设置dial值的范围*/
23 dial->setRange(0,100);
24
25 /* 开启后可指向圆的任何角度*/
26 //dial->setWrapping(true);
27
28 /* 实例化对象和设置显示位置与大小*/
29 label = new QLabel(this);
30 label->setGeometry(370, 300, 200, 50);
31
32 /* 初始化为0km/h */
33 label->setText("0km/h");
34
35 /* 信号槽连接*/
36 connect(dial, SIGNAL(valueChanged(int)),
37 this, SLOT(dialValueChanged(int)));
38 }
39
40 MainWindow::~MainWindow()
41 {
42 }
43
44 void MainWindow::dialValueChanged(int val)
45 {
46 /* QString::number()转换成字符串*/
47 label->setText(QString::number(val) + "km/h");
48 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,当程序初始化时,QDial 控件的显示如下(注意,windows 下QDial 控件显示的格式可能不一样,下图为linux 下的QDial 控件的显示样式)。当用鼠标拖动滑块或者按键盘的上下左右方向键时,label 则会显示当前“车速”。
在这里插入图片描述
QDial 在很多场合都能使用,比如音量控制,汽车仪表盘,芝麻信用分等场合都可以使用到,只是需要我们有这个创意和想法,还需要个人的美工基础。

QScrollBar

7.2.12.1 控件简介
QScrollBar 继承QAbstractSlider。QScrollBar 小部件提供垂直或水平滚动条,允许用户访问比用于显示文档的小部件大的文档部分。它提供了用户在文档中的当前位置和可见文档数量的可视化指示。滚动条通常配有其他控件,可以实现更精确的导航(这里指浏览到精确的位置)。
7.2.12.2 用法示例
例19_qscrollbar 创建水平和垂直滚动条(难度:简单),使用QScrollBar 类实例化两个控件,一个是水平滚动条,另一个是垂直滚动条,中间用一个标签文本来显示。(本例只创建实例,不对效果进行细化(请注意:一般水平或垂直滚动条都用QScrollArea 搭配其他控件使用,不单独使用QScrollBar 去创建滚动条,有些控件“自带”滚动条,例如QListWidget 等,都可以
用QScrollArea 来设置它的属性)。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QScrollBar >
6 # include < QLabel >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明水平滚动条对象*/
	18 QScrollBar * horizontalScrollBar;
	19
	20      /* 声明垂直滚动条对象*/
	21 QScrollBar * verticalScrollBar;
	22
	23      /* 声明标签文本*/
	24 QLabel * label;
	25
};
26 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置主窗体大小,位置*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9       /* 实例化水平滚动条及设置位置大小*/
	10 horizontalScrollBar = new QScrollBar( Qt::Horizontal, this );
	11 horizontalScrollBar->setGeometry( 0, 450, 800, 30 );
	12
	13      /* 实例化垂直滚动条及设置位置大小*/
	14 verticalScrollBar = new QScrollBar( Qt::Vertical, this );
	15 verticalScrollBar->setGeometry( 770, 0, 30, 480 );
	16
	17      /* 实例化,标签文本*/
	18 label = new QLabel( this );
	19      /* 设置文本*/
	20 label->setText( "这是一个测试" );
	21      /* 设置位置大小*/
	22 label->setGeometry( 300, 200, 100, 20 );
	23
}


24
25 MainWindow::~MainWindow()
26
{
	27
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}

运行效果
程序编译运行的结果。如下当程序初始化时,滚动条控件的显示如下(注意,windows 下滚动条控件显示的格式可能不一样,下图为linux 下的滚动条控件的显示样式)。
在这里插入图片描述

QSlider

7.2.13.1 控件简介
QSlider 继承QAbstractSlider。QScrollBar 类提供垂直或水平滑动条小部件,滑动条是用于控制有界值的典型小部件。它允许用户沿着水平或垂直凹槽移动滑块手柄,并将手柄的位置转换为合法范围内的整数值。
7.2.13.2 用法示例
例20_qslider 创建水平和垂直滑动条(难度:简单)创建两个QSlider 对象,一个是水平滑动条,另一个是垂直滑动条;用一个Label 来显示当前水平或垂直滑动条当前的值。设置水平滑动条与水平滑动条相互关联,通过滑动其中一个滑动条的值相应的也会改变另一个滑动条的值。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QSlider >
6 # include < QLabel >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明对象*/
	18 QSlider * horizontalSlider;
	19 QSlider * verticalSlider;
	20 QLabel * label;
	21 private slots:
	22      /* 槽函数*/
	23 void horizontalSliderValueChanged( int );


	24 void verticalSliderValueChanged( int );


	25
	26
};
27 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 this->setGeometry(0, 0, 800, 480);
7
8 /* 实例化水平滑动条对象*/
9 horizontalSlider = new QSlider(Qt::Horizontal, this);
10
11 /* 设置显示的位置与大小*/
12 horizontalSlider->setGeometry(250, 100, 200, 20);
13
14 /* 设置值范围*/
15 horizontalSlider->setRange(0, 100);
16
17 /* 实例化垂直滑动条对象*/
18 verticalSlider = new QSlider(Qt::Vertical, this);
19
20 /* 设置显示的位置与大小*/
21 verticalSlider->setGeometry(200, 50, 20, 200);
22
23 /* 设置值范围*/
24 verticalSlider->setRange(0, 100);
25
26 /* 实例化标签文本*/
27 label = new QLabel("滑动条值:0", this);
28 label->setGeometry(250, 200, 100, 20);
29
30 /* 信号槽连接*/
31 connect(horizontalSlider, SIGNAL(valueChanged(int)),
32 this, SLOT(horizontalSliderValueChanged(int)));
33 connect(verticalSlider, SIGNAL(valueChanged(int)),
34 this, SLOT(verticalSliderValueChanged(int)));
35
36 }
37
38 MainWindow::~MainWindow()
39 {
40 }
41
42 void MainWindow::horizontalSliderValueChanged(int val)
43 {
44 /* 当水平滑动条的值改变时,改变垂直滑动条的值*/
45 verticalSlider->setSliderPosition(val);
46
47 /* 将int类型转变成字符*/
48
49 QString str = "滑动条值:" + QString::number(val);
50
51 /* 显示当前垂直或水平滑动条的值*/
52 label->setText(str);
53
54 }
55
56 void MainWindow::verticalSliderValueChanged(int val)
57 {
58 /* 当垂直滑动条的值改变时,改变水平滑动条的值*/
59 horizontalSlider->setSliderPosition(val);
60 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。当程序初始化时,滑动条控件的显示如下(注意,windows 下滑动条控件显示的格式可能不一样,下图为linux 下的滑动条控件的显示样式)。Label 显示的初始值为0,当拖动任意一个滑动条来改变当前的值,另一个滑动条的值也在变。
在这里插入图片描述

QKeySequenceEdit

7.2.14.1 控件简介
QKeySequenceEdit 继承QWidget。这个小部件允许用户选择QKeySequence, QKeySequence通常用作快捷方式。当小部件接收到焦点并在用户释放最后一个键后一秒结束时,将启动记录,通常用作记录快捷键。
7.2.14.2 用法示例
例21_qkeysequenceedit 自定义快捷键(难度:简单),通常KeySequenceEdit 控件记录快捷键后与Qt 键盘事件搭配来使用,由于教程后面才说到事件,所以先不与Qt 键盘事件搭配使用。
下面使用一个QKeySequenceEdit 控件,然后判断输入的组合键是否为Ctrl + Q,若是,则关闭窗口,退出程序,如果不是,则继续更新记录组合键。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QKeySequenceEdit >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* 声明QKeySequenceEdit对象*/
	17 QKeySequenceEdit * keySequenceEdit;
	18
	19 private slots:
	20      /* 声明槽*/
	21 void KSEKeySequenceChanged( const QKeySequence & );


	22
	23
};
24 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 #include <QDebug>
3
4 MainWindow::MainWindow(QWidget *parent)
5 : QMainWindow(parent)
6 {
7 /* 主窗体设置位置与大小*/
8 this->setGeometry(0, 0, 800, 480);
9
10 /* 实例化*/
11 keySequenceEdit = new QKeySequenceEdit(this);
12
13 /* 设置位置与大小*/
14 keySequenceEdit->setGeometry(350, 200, 150, 30);
15
16 /* 信号槽连接*/
17 connect(keySequenceEdit,
18 SIGNAL(keySequenceChanged(const QKeySequence &)),
19 this,
20 SLOT(KSEKeySequenceChanged(const QKeySequence &))
21 );
22
23 }
24
25 MainWindow::~MainWindow()
26 {
27 }
28
29 void MainWindow::KSEKeySequenceChanged(
30 const QKeySequence &keySequence)
31 {
32 /* 判断输入的组合键是否为Ctrl + Q,如果是则退出程序*/
33 if(keySequence == QKeySequence(tr("Ctrl+Q"))) {
34 /* 结束程序*/
35 this->close();
36 }else {
37 /* 打印出按下的组合键*/
38 qDebug()<<keySequence.toString()<<endl;
39 }
40 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。(注意Windows 下显示效果可能不同,下图为linux 下运行的结果),当焦点在KeySequenceEdit 里时,按下键盘里的任一键或者组合键,一秒后,KeySequenceEdit 将记录了这个/这组组合键,并打印在输出信息里。直到程序按下Ctrl + Q 组合键后,程序窗口才关闭,结束。
在这里插入图片描述

显示窗口部件

Qt Designer 显示窗口部件提供的面板中,提供了10 种显示小部件。在Qt5.5 以前的Qt5 版本这个显示窗口部件还有一个QWebview 部件,在Qt5.6 开始就被移除了,取而代之的是QWebengine,但是QWebengine 不是以小部件的形式在这个显示窗口部件里显示。
在这里插入图片描述
(1)Label:标签
(2)Text Browser:文本浏览器
(3)Graphics View:图形视图
(4)Calendar Widget:日历
(5)LCD Number:液晶数字
(6)Progress Bar:进度条
(7)Horizontal Line:水平线
(8)Vertial Line:垂直线
(9)OpenGL Widget:开放式图形库工具
(10)QQuick Widget:嵌入式QML 工具
这十六种按钮部件作用简介如下:
QLabel提供了一种用于文本或图像显示的小部件,在前4.1 与4.2 某些小节已经出现过Label控件,只用了它显示文本,其实它还可以用于显示图像。
QCalendarWidget 继承QWidget。QCalendarWidget 类提供了一个基于月的日历小部件,允许用户选择日期。CalendarWidget 小部件是用当前月份和年份初始化的,QCalendarWidget 还提供了几个公共插槽来更改显示的年份和月份。
QLCDNumber 继承QFrame。QLCDNumber 小部件显示一个类似于lcd 的数字。QLCDNumber 小部件可以显示任意大小的数字。它可以显示十进制、十六进制、八进制或二进制数字。
使用display()插槽很容易连接到数据源,该插槽被重载以接受五种参数类型中的任何一种。
QProgressBar 继承QWidget。QProgressBar 小部件提供了一个水平或垂直的进度条。进度条用于向用户显示操作的进度,并向他们确认应用程序仍在运行。
QFrame 继承QWidget。QFrame 类是有框架的窗口部件的基类,它绘制框架并且调用一个虚函数drawContents()来填充这个框架。这个函数是被子类重新实现的。这里至少还有两个有用的函数:drawFrame()和frameChanged()。
QTextBrowser 继承QTextEdit,QTextBrowser 类提供了一个具有超文本导航的文本浏览器。
该类扩展了QTextEdit(在只读模式下),添加了一些导航功能,以便用户可以跟踪超文本文档中的链接。
QGraphicsView 继承QAbstractScrollArea。QGraphicsView 是图形视图框架的一部分,它提供了基于图元的模型/视图编程。QGraphicsView 在可滚动视图中可视化QGraphicsScene 的内容。
要创建带有几何项的场景,请参阅QGraphicsScene 的文档。
要可视化场景,首先构造一个QGraphicsView 对象,将要可视化的场景的地址传递给QGraphicsView 的构造函数。或者,可以调用setScene()在稍后设置场景。
Text Browser (文本浏览器)、Graphics View(图形视图)、OpenGL Widget(开放式图形库工具)、QQuick Widget(嵌入式QML 工具)将不在本小节介绍,其中Text Browser (文本浏览器)、GraphicsView(图形视图)在7.4 小节显示窗口之浏览器介绍。

QLabel

7.3.1.1 控件简介
QLabel 提供了一种用于文本或图像显示的小部件,在前7.2.11、7.2.12 等小节已经出现过Label 控件,只用了它显示文本,其实它还可以用于显示图像。
7.3.1.2 用法示例
例22_qlbel 标签显示图像或文本(难度简单),前面已经在某些小节出现过label 了,但只是用来显示文本内容,实际上像button(按钮),widget,label 等都是可以用来显示图像的。只是button 不常用来显示单张图像,因为button 是有三种状态,分别是按下,释放,悬停。所以它不常用于单单显示一张图像。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
本例已经添加一张资源图片,如果不清楚如何添加资源图片,请参考7.1.4 小节。添加完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QLabel >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* 用一个QLabel对象用于显示字符串*/
	17 QLabel * labelString;
	18
	19      /* 用一个QLabel对象用于显示图像*/
	20 QLabel * labelImage;
	21
};
22 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QLabel >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* 用一个QLabel对象用于显示字符串*/
	17 QLabel * labelString;
	18
	19      /* 用一个QLabel对象用于显示图像*/
	20 QLabel * labelImage;
	21
};
22 # endif      /* MAINWINDOW_H */

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。为了避免引起图像被压缩或者拉伸,本次设置标签的大小为452*132,这是根据图像的实际大小来设置的。

在这里插入图片描述

QCalendarWidget

控件简介

QCalendarWidget 继承QWidget。QCalendarWidget 类提供了一个基于月的日历小部件,允许用户选择日期。CalendarWidget 小部件是用当前月份和年份初始化的,QCalendarWidget 还提供了几个公共插槽来更改显示的年份和月份。

用法示例
例23_qcalendarwidget 日历简单的使用(难度:简单),本例只是简单的使用日历控件来达到一定的效果。使用一个CalendarWidget 控件,一个Label 来显示当前日历所选择的日期,一个pushButton 按钮,点击pushButton 按钮来回到当前系统的日期。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QCalendarWidget >
6 # include < QPushButton >
7 # include < QLabel >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 声明QCalendarWidget,QPushButton,QLabel对象*/
	19 QCalendarWidget * calendarWidget;
	20 QPushButton * pushButton;
	21 QLabel * label;
	22
	23 private slots:
	24      /* 槽函数*/
	25 void calendarWidgetSelectionChanged();


	26 void pushButtonClicked();


	27
	28
};
29 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置位置与大小,下同*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 对象实例化设置显示的位置与大小*/
10 calendarWidget = new QCalendarWidget(this);
11 calendarWidget->setGeometry(200, 20, 400, 300);
12
13 QFont font;
14 /* 设置日历里字体的大小为10像素*/
15 font.setPixelSize(10);
16 calendarWidget->setFont(font);
17
18 /* 对象实例化设置显示的位置与大小*/
19 pushButton = new QPushButton("回到当前日期",this);
20 pushButton->setGeometry(200, 350, 100, 30);
21
22 /* 对象实例化设置显示的位置与大小*/
23 label = new QLabel(this);
24 label->setGeometry(400, 350, 400, 30);
25 QString str = "当前选择的日期:"
26 + calendarWidget->selectedDate().toString();
27 label->setText(str);
28
29 /* 信号槽连接*/
30 connect(calendarWidget, SIGNAL(selectionChanged()),
31 this, SLOT(calendarWidgetSelectionChanged()));
32 connect(pushButton, SIGNAL(clicked()),
33 this, SLOT(pushButtonClicked()));
34 }
35
36 MainWindow::~MainWindow()
37 {
38 }
39
40 void MainWindow::calendarWidgetSelectionChanged()
41 {
42 /* 当日历点击改变当前选择的期时,更新Label的显示内容*/
43 QString str = "当前选择的日期:"
44 + calendarWidget->selectedDate().toString();
45 label->setText(str);
46 }
47
48 void MainWindow::pushButtonClicked()
49 {
50 /* 设置当前选定的日期为系统的QDate */
51 calendarWidget->setSelectedDate(QDate::currentDate());
52 }
53

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。当程序运行后,可以通过点击鼠标或键盘来改变当前选定的日期,label 标签则会改变为当前选定的日期,当点击回到当前日期按钮后,日历会改变当前选定的日期并且把当前选定的日期改变为系统当前的日期。拓展:可以用日历来设置生日,日期提醒等,还可以做成一个华丽的系统日历界面等。
在这里插入图片描述

QLCDNumber

7.3.3.1 控件简介
QLCDNumber 继承QFrame 。QLCDNumber 小部件显示一个类似于lcd 的数字。
QLCDNumber 小部件可以显示任意大小的数字。它可以显示十进制、十六进制、八进制或二进制数字。使用display()插槽很容易连接到数据源,该插槽被重载以接受五种参数类型中的任何一种。
7.3.3.2 用法示例
例24_qlcdnumber,LCDNumber 时钟(难度:简单),使用一个LCDNumber 控件作时钟的显示,一个定时器定时更新LCDNumber 的时间。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QMainWindow >
6 # include < QLCDNumber >
7 # include < QTimer >
8 # include < QTime >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19      /* 声明QLCDNumber对象*/
	20 QLCDNumber * lcdNumber;
	21
	22      /* 声明QTimer对象*/
	23 QTimer * timer;
	24
	25 private slots:
	26      /* 槽函数*/
	27 void timerTimeOut();


	28
	29
};
30 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置主窗体的大小与位置*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化与设置显示的位置大小*/
10 lcdNumber = new QLCDNumber(this);
11 lcdNumber->setGeometry(300, 200, 200, 50);
12
13 /* 设置显示的位数8位*/
14 lcdNumber->setDigitCount(8);
15 /* 设置样式*/
16 lcdNumber->setSegmentStyle(QLCDNumber::Flat);
17
18 /* 设置lcd显示为当前系统时间*/
19 QTime time = QTime::currentTime();
20
21 /* 设置显示的样式*/
22 lcdNumber->display(time.toString("hh:mm:ss"));
23
24 timer = new QTimer(this);
25 /* 设置定时器1000毫秒发送一个timeout()信号*/
26 timer->start(1000);
27
28 /* 信号槽连接*/
29 connect(timer, SIGNAL(timeout()), this,
30 SLOT(timerTimeOut()));
31
32 }
33
34 MainWindow::~MainWindow()
35 {
36 }
37
38 void MainWindow::timerTimeOut()
39 {
40 /* 当定时器计时1000毫秒后,刷新lcd显示当前系统时间*/
41 QTime time = QTime::currentTime();
42 /* 设置显示的样式*/
43 lcdNumber->display(time.toString("hh:mm:ss"));
44 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。程序运行后,可以看到时间为当前系统的时间,LCDNumber时钟显示系统时钟的时钟并运行着。
在这里插入图片描述

QProgressBar

7.3.4.1 控件简介
QProgressBar 继承QWidget。QProgressBar 小部件提供了一个水平或垂直的进度条。进度条用于向用户显示操作的进度,并向他们确认应用程序仍在运行。
7.3.4.2 用法示例
例25_qprogressbar,手机电池充电。用一个QProgressBar 模拟手机电池充电。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
本例已经添加一张电池的背景图资源图片,如果不清楚如何添加资源图片,请参考7.1.4小节。添加完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QProgressBar >
6 # include < QTimer >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 声明对象*/
	18 QProgressBar * progressBar;
	19 QTimer * timer;
	20
	21      /* 用于设置当前QProgressBar的值*/
	22 int value;
	23
	24 private slots:
	25      /* 槽函数*/
	26 void timerTimeOut();


	27
	28
};
29 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6                                                       /* 设置主窗体位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9 progressBar = new QProgressBar( this );
	10 progressBar->setGeometry( 300, 200, 200, 60 );
	11
	12                                                      /*样式表设置,常用使用setStyleSheet来设置样式(实现界面美化的功能),
	                                                         * 13 * 具体可参考styleSheet */
	14 progressBar->setStyleSheet(
		15 "QProgressBar{border:8px solid #FFFFFF;"
		16 "height:30;"
		17 "border-image:url(:/images/battery.png);"    /* 背景图片 */
		18 "text-align:center;"                         /* 文字居中 */
		19 "color:rgb(255,0,255);"
		20 "font:20px;"                                 /* 字体大小为20px */
		21 "border-radius:10px;}"
		22 "QProgressBar::chunk{"
		23 "border-radius:5px;"                         /* 斑马线圆角 */
		24 "border:1px solid black;"                    /* 黑边,默认无边 */
		25 "background-color:skyblue;"
		26 "width:10px;margin:1px;}"                    /* 宽度和间距 */
		27 );
	28
	29                                                      /* 设置progressBar的范围值*/
	30 progressBar->setRange( 0, 100 );
	31                                                      /* 初始化value为0 */
	32 value = 0;
	33                                                      /* 给progressBar设置当前值*/
	34 progressBar->setValue( value );
	35                                                      /* 设置当前文本字符串的显示格式*/
	36 progressBar->setFormat( "充电中%p%" );
	37
	38                                                      /* 定时器实例化设置每100ms发送一个timeout信号*/
	39 timer = new QTimer( this );
	40 timer->start( 100 );
	41
	42                                                      /* 信号槽连接*/
	43 connect( timer, SIGNAL( timeout() ),
		    44 this, SLOT( timerTimeOut() ) );
	45
}


46
47 MainWindow::~MainWindow()
48
{
	49
}


50
51 void MainWindow::timerTimeOut()
52
{
	53      /* 定显示器时间到,value值自加一*/
	54 value++;
	55 progressBar->setValue( value );
	56      /* 若value值大于100,令value再回到0 */
	57 if ( value > 100 )
		58 value = 0;
	59
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。程序运行后,可以看到在定时器的作用下,电池一直在充电,充到100%,又重新回到0%重新充电。QProgressBar 一般用于表示进度,常用于如复制进度,打开、加载进度等。
在这里插入图片描述

QFrame

7.3.5.1 控件简介
QFrame 继承QWidget。QFrame 类是有框架的窗口部件的基类,它绘制框架并且调用一个虚函数drawContents()来填充这个框架。这个函数是被子类重新实现的。这里至少还有两个有用的函数:drawFrame()和frameChanged()。
QPopupMenu 使用这个来把菜单“升高”,高于周围屏幕。QProgressBar 有“凹陷”的外观。
QLabel 有平坦的外观。这些有框架的窗口部件可以被改变。
QFrame::Shape 这个枚举类型定义了QFrame 的框架所使用的外形。当前定义的效果有:
NoFrame - QFrame 不画任何东西
Box - QFrame 在它的内容周围画一个框
Panel - QFrame 画一个平板使内容看起来凸起或者凹陷
WinPanel - 像Panel,但QFrame 绘制三维效果的方式和Microsoft Windows 95(及其它)的一样
ToolBarPanel - QFrame 调用QStyle::drawToolBarPanel()
MenuBarPanel - QFrame 调用QStyle::drawMenuBarPanel()
HLine - QFrame 绘制一个水平线,但没有框任何东西(作为分隔是有用的)
VLine - QFrame 绘制一个竖直线,但没有框任何东西(作为分隔是有用的)
StyledPanel - QFrame 调用QStyle::drawPanel()
PopupPanel - QFrame 调用QStyle::drawPopupPanel()
阴影风格有:
Plain 使用调色板的前景颜色绘制(没有任何三维效果)。
Raised 使用当前颜色组的亮和暗颜色绘制三维的凸起线。
Sunken 使用当前颜色组的亮和暗颜色绘制三维的凹陷线。

7.3.5.2 用法示例
例26_qframe,水平/垂直线(难度:简单),定义两个QFrame 对象,实例化后设置成一条水平样式,一条垂直样式。实际上Display Widgets 里的Horizontal Line/Vertical Line 是QFrame已经封装好的控件,也可以通过下面的例子来实现不同的效果。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QFrame >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* 声明对象*/
	17 QFrame * hline;
	18 QFrame * vline;
	19
	20
};
21 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置主窗体的显示位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9       /* 实例化*/
	10 hline = new QFrame( this );
	11      /* 确定起始点,设置长和宽,绘制距形*/
	12 hline->setGeometry( QRect( 200, 100, 400, 40 ) );
	13
	14      /* 设置框架样式为Hline,水平,可设置为其他样式例如Box,
	         * 15 * 由于是样式选择HLine,所以只显示一条水平直线
	         * 16 */
	17 hline->setFrameShape( QFrame::HLine );
	18      /* 绘制阴影*/
	19 hline->setFrameShadow( QFrame::Sunken );
	20
	21      /* 实例化*/
	22 vline = new QFrame( this );
	23      /* 确定起始点,设置长和宽,绘制距形*/
	24 vline->setGeometry( QRect( 300, 100, 2, 200 ) );
	25
	26      /* 设置框架样式为Vline,垂直,可设置为其他样式例如Box,
	         * 27 * 由于是样式选择Vline,所以只显示一条垂直直线
	         * 28 */
	29 vline->setFrameShape( QFrame::VLine );
	30      /* 绘制阴影*/
	31 vline->setFrameShadow( QFrame::Sunken );
	32
}


33
34 MainWindow::~MainWindow()
35
{
	36
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。在窗口中央出现一条垂直的直线和一条水平的直线。可以用QFrame 来绘制一些比较好看的边框等,用作美化界面。QFrame 类是所有框架的窗口部件的基类,所以像QLabel 这种见的控件也可以设置成独特的边框样式。
在这里插入图片描述

显示窗口部件之浏览器

QTextBrowser

7.4.1.1 控件简介
QTextBrowser 继承QTextEdit,QTextBrowser 类提供了一个具有超文本导航的文本浏览器。
该类扩展了QTextEdit(在只读模式下),添加了一些导航功能,以便用户可以跟踪超文本文档中的链接。
7.4.1.2 用法示例
例27_qtextbrowser,简单的文本浏览器(难度:简单),本例设计一个文本浏览器程序,可以打开并显示txt、html 等文件。本小节还用到QAction,菜单栏,学习文件的打开以及处理等。
在新建例程默认继承QMainWindow 类即可。勾选mainwindow.ui,因为我们要在工具栏里添加按钮来打开文件等操作。新建项目完成如下。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTextBrowser >
6
7 QT_BEGIN_NAMESPACE
8 namespace Ui { class MainWindow; }
9 QT_END_NAMESPACE
10
11 class MainWindow : public QMainWindow
	12 {
	13 Q_OBJECT
	14
	15 public:
	16 MainWindow( QWidget *parent = nullptr );
	17 ~MainWindow();
	18
	19 private:
	20 Ui::MainWindow * ui;
	21      /* 声明对象*/
	22 QTextBrowser * textBrowser;
	23 QAction * openAction;
	24
	25 private slots:
	26      /* 槽函数*/
	27 void openActionTriggered();


	28
};
29 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include "ui_mainwindow.h"
3 /* 窗口对话框与文本流*/
4 # include < QFileDialog >
5 # include < QTextStream >
6
7 MainWindow::MainWindow( QWidget *parent )
8 : QMainWindow( parent )
	9, ui( new Ui::MainWindow )
	10
{
	11 ui->setupUi( this );
	12      /* 设置主窗体位置与大小*/
	13 this->setGeometry( 0, 0, 800, 480 );
	14
	15      /* 将窗口标题设置为文本浏览器*/
	16 this->setWindowTitle( "文本浏览器" );
	17
	18      /* 实例化*/
	19 textBrowser = new QTextBrowser( this );
	20      /* 将文本浏览器窗口居中*/
	21 this->setCentralWidget( textBrowser );
	22
	23      /* 实例化*/
	24 openAction = new QAction( "打开", this );
	25      /* ui窗口自带有menubar(菜单栏)、mainToolbar(工具栏)与
	         * 26 * statusbar(状态栏)
	         * 27 * menuBar是ui生成工程就有的,所以可以在menubar里添加
	         * 28 * 我们的QActiont等,如果不需要menubar,可以在ui设计
	         * 29 * 窗口里,在右则对象里把menubar删除,再自己重新定义自己的
	         * 30 * 菜单栏
	         * 31 */
	32      /* 将动作添加到菜单栏*/
	33 ui->menubar->addAction( openAction );
	34
	35      /* 信号槽连接*/
	36 connect( openAction, SIGNAL( triggered() ),
		    37 this, SLOT( openActionTriggered() ) );
	38
	39
}


40
41 MainWindow::~MainWindow()
42
{
	43 delete ui;
	44
}


45
46 void MainWindow::openActionTriggered()
47
{
	48      /* 调用系统打开文件窗口,过滤文件名*/
	49 QString fileName = QFileDialog::getOpenFileName(
		50 this, tr( "打开文件" ), "",
		51 tr( "Files(*.txt *.cpp *.h *.html *.htm)" )
		52 );
	53 QFile myFile( fileName );
	54      /* 以只读、文本方式打开,若打开失败,则返回*/
	55 if ( !myFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
		56 return;
	57
	58      /* 用QTextStream对象接收*/
	59 QTextStream in( &myFile );
	60
	61      /* 读取全部数据*/
	62 QString myText = in.readAll();
	63
	64      /* 判断打开文件的后缀,如果是html格式的则设置文本浏览器为html格式*/
	65 if ( fileName.endsWith( "html" ) || fileName.endsWith( "htm" ) )
	{
		66 textBrowser->setHtml( myText );
		67
	} else {
		68 textBrowser->setPlainText( myText );
		69
	}
	70
	71 /* ui窗口自带有statusbar(状态栏),设置打开的文件名*/
	72 ui->statusbar->showMessage( "文件名:" + fileName );
	73
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。在菜单栏点击打开后,系统默认是打开的最近打开的位置,选择任意一个可打开的文件,本次打开的是该工程中的mainwindow.cpp 文件,结果如下图。根据上面的例子可自行拓展打造自己的文本浏览器,例如在菜单栏上加上关闭动作等,在工具栏还可以添加字体颜色,与及背景颜色,以及字体的放大与缩小等,可自行拓展。(备注:经测试
Ubuntu16 的Qt 程序异常,看不到菜单栏,所以看不到“打开”这个按钮,Ubuntu18 显示正常。)

在这里插入图片描述

QGraphicsView

小节前言:
在这里主要是简单介绍QGraphicsView 这种框架类的介绍与常用接口,实际上这种框架过于复杂,我们也不能在这一小节完全展现,下面就让我们快速去了解QGraphicsView 图形视图框架类吧!
7.4.2.1 控件简介
QGraphicsView 继承QAbstractScrollArea。QGraphicsView 是图形视图框架的一部分,它提供了基于图元的模型/视图编程。QGraphicsView 在可滚动视图中可视化QGraphicsScene 的内容。
要创建带有几何项的场景,请参阅QGraphicsScene 的文档。
要可视化场景,首先构造一个QGraphicsView 对象,将要可视化的场景的地址传递给QGraphicsView 的构造函数。或者,可以调用setScene()在稍后设置场景。
7.4.2.2 用法示例
例28_qgraphicsview,简单的图像浏览器(难度:简单),本例设计一个图像浏览器程序,在上一节一的基础上,将它改变为图像浏览器。
在新建例程默认继承QMainWindow 类即可。勾选mainwindow.ui,因为我们要在工具栏里添加按钮来打开文件等操作。新建项目完成如下。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QGraphicsView >
6
7 QT_BEGIN_NAMESPACE
8 namespace Ui { class MainWindow; }
9 QT_END_NAMESPACE
10
11 class MainWindow : public QMainWindow
	12 {
	13 Q_OBJECT
	14
	15 public:
	16 MainWindow( QWidget *parent = nullptr );
	17 ~MainWindow();
	18
	19 private:
	20 Ui::MainWindow * ui;
	21      /* 声明对象*/
	22 QGraphicsView * graphicsView;
	23 QGraphicsScene * graphicsScene;
	24 QAction * openAction;
	25
	26 private slots:
	27      /* 槽函数*/
	28 void openActionTriggered();


	29
	30
};
31 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3 #include <QFileDialog>
4
5 MainWindow::MainWindow(QWidget *parent)
6 : QMainWindow(parent)
7 , ui(new Ui::MainWindow)
8 {
9 ui->setupUi(this);
10 /* 设置主窗体大小*/
11
12 this->setGeometry(0, 0, 800, 480);
13 /* 将窗口标题设置为图像浏览器*/
14 this->setWindowTitle("图像浏览器");
15
16 /* 实例化图形视图对象*/
17 graphicsView = new QGraphicsView(this);
18 /* 将图像浏览器窗口居中*/
19 this->setCentralWidget(graphicsView);
20
21 /* 实例化场景对象*/
22 graphicsScene = new QGraphicsScene(this);
23
24 /* 在QGraphicsView设置场景*/
25 graphicsView->setScene(graphicsScene);
26
27 /* 将动作添加到菜单栏*/
28 openAction = new QAction("打开",this);
29 ui->menubar->addAction(openAction);
30
31 /* 信号槽连接*/
32 connect(openAction, SIGNAL(triggered()),
33 this, SLOT(openActionTriggered()));
34 }
35
36 MainWindow::~MainWindow()
37 {
38 delete ui;
39 }
40
41 void MainWindow::openActionTriggered()
42 {
43 /*调用系统打开文件窗口,设置窗口标题为“打开文件”,过滤文件名*/
44 QString fileName = QFileDialog::getOpenFileName(
45 this,tr("打开文件"), "",
46 tr("Files(*.png *.jpg *.bmp)")
47 );
48 /* 定义QPixmap对象,指向fileName */
49 QPixmap image(fileName);
50 /* 将image用scaled来重新设置长宽为graphicsView的长宽,
51 * 保持纵横比等
52 */
53
54 /* 假若用户没选择文件,则返回*/
55 if(image.isNull())
56 return;
57 image = image.scaled(graphicsView->width(),
58 graphicsView->height(),
59 Qt::KeepAspectRatio,
60 Qt::FastTransformation
61 );
62 /* 在添加场景内容前,先清除之前的场景内容*/
63 graphicsScene->clear();
64 /* 添加场景内容image */
65 graphicsScene->addPixmap(image);
66 /* ui窗口自带有statusBar(状态栏),设置打开的文件名*/
67 ui->statusbar->showMessage("文件名:" + fileName);
68 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。菜单栏点击打开后,系统默认是打开的最近打开的位置,选择任意一个可打开的图片。(备注:本例所展示的图片已经放在工程目录下)。
在这里插入图片描述

布局管理

Qt 提供了非常丰富的布局类,基本布局管理类包括:QBoxLayout、QGridLayout、QFormLayout 和QStackedLayout。这些类都从QLayout 继承而来,它们都来源于QObject(而不是QWidget)。创建更加复杂的布局,可以让它们彼此嵌套完成。
其中QBoxLayout 提供了水平和垂直的布局管理;QFormLayout 提供了将输入部件和标签成组排列的布局管理;QGridLayout 提供了网格形式的布局管理;QStackedLayout 提供了一组布局后的部件,可以对它们进行分布显示。
它们的继承关系如下图。
在这里插入图片描述
下面将学习Layouts 组里面的4 种布局,如下图。
在这里插入图片描述
各个控件的名称依次解释如下。
(1)Vertiacl Layout:垂直布局
(2)Horizontal Layout:水平布局
(3)Grid Layout:网格布局
(4)Form Layout:表单布局
QBoxLayout 继承QLayout。QBoxLayout 类提供水平或垂直地排列子部件。QBoxLayout 获取从它的父布局或从parentWidget()中所获得的空间,将其分成一列框,并使每个托管小部件填充一个框。
QGridLayout 继承QLayout。QGridLayout 获取可用的空间(通过其父布局或parentWidget())),将其分为行和列,并将其管理的每个小部件放入正确的单元格中。由于网格布局管理器中的组件也是会随着窗口拉伸而发生变化的,所以也是需要设置组件之间的比例系数的,与QBoxLayout 不同的是网格布局管理器还需要分别设置行和列的比例系数。
QFormLayout 继承QLayout。QFormLayout 类管理输入小部件及其关联标签的表单。QFormLayout 是一个方便的布局类,它以两列的形式布局其子类。左列由标签组成,右列由“字段”小部件(QLineEdit(行编辑器)、QSpinBox(旋转框等))组成。通常使用setRowWrapPolicy(RowWrapPolicy policy)接口函数设置布局的换行策略进行布局等。

QBoxLayout

7.5.1.1 控件简介
QBoxLayout 继承QLayout。QBoxLayout 类提供水平或垂直地排列子部件。QBoxLayout 获取从它的父布局或从parentWidget()中所获得的空间,将其分成一列框,并使每个托管小部件填充一个框。
7.5.1.2 用法示例
例29_qboxlayout,垂直或水平布局(难度:简单),使用几个按钮,将他们设置为垂直排布和水平排布,以及设置它们的一些属性。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QHBoxLayout >
6 # include < QVBoxLayout >
7 # include < QPushButton >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 声明按钮对象数组*/
	19 QPushButton * pushButton[6];
	20
	21      /* 定义两个widget,用于容纳排布按钮*/
	22 QWidget * hWidget;
	23 QWidget * vWidget;
	24
	25      /* QHBoxLayout与QVBoxLayout对象*/
	26 QHBoxLayout * hLayout;
	27 QVBoxLayout * vLayout;
	28
	29
};
30 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QList >
3
4 MainWindow::MainWindow( QWidget *parent )
5 : QMainWindow( parent )
	6
{
	7       /* 设置主窗口的位置与大小*/
	8 this->setGeometry( 0, 0, 800, 480 );
	9
	10      /* 实例化与设置位置大小*/
	11 hWidget = new QWidget( this );
	12 hWidget->setGeometry( 0, 0, 800, 240 );
	13
	14 vWidget = new QWidget( this );
	15 vWidget->setGeometry( 0, 240, 800, 240 );
	16
	17 hLayout	= new QHBoxLayout();
	18 vLayout	= new QVBoxLayout();
	19
	20                      /* QList<T>是Qt的一种泛型容器类。
	                         * 21 * 它以链表方式存储一组值,
	                         * 22 * 并能对这组数据进行快速索引
	                         * 23 */
	24 QList <QString>list;
	25                      /* 将字符串值插入list */
	26 list << "one" << "two" << "three" << "four" << "five" << "six";
	27
	28                      /* 用一个循环实例化6个按钮*/
	29 for ( int i = 0; i < 6; i++ )
	{
		30 pushButton[i] = new QPushButton();
		31 pushButton[i]->setText( list[i] );
		32 if ( i < 3 )
		{
			33      /* 将按钮添加至hLayout中*/
			34 hLayout->addWidget( pushButton[i] );
			35
		} else {
			36      /* 将按钮添加至vLayout中*/
			37 vLayout->addWidget( pushButton[i] );
			38
		}
		39
	}
	40                      /* 设置间隔为50 */
	41 hLayout->setSpacing( 50 );
	42
	43                      /* hWidget与vWidget的布局设置为hLayout/vLayout */
	44 hWidget->setLayout( hLayout );
	45 vWidget->setLayout( vLayout );
	46
}


47
48 MainWindow::~MainWindow()
49
{
	50
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。可以看到在hWidget 中添加了3 个水平排布的按钮,在vWidget中添加了3 个垂直排布的按钮。
在这里插入图片描述

QGridLayout

7.5.2.1 控件简介
QGridLayout 类提供了布局管理器里的一种以网格(二维)的方式管理界面组件,以按钮组件为例,它们所对应网格的坐标下表,与二维数组类似。
在这里插入图片描述
QGridLayout 继承QLayout。QGridLayout 获取可用的空间(通过其父布局或parentWidget())),将其分为行和列,并将其管理的每个小部件放入正确的单元格中。由于网格布局管理器中的组件也是会随着窗口拉伸而发生变化的,所以也是需要设置组件之间的比例系数的,与QBoxLayout 不同的是网格布局管理器还需要分别设置行和列的比例系数。
7.5.2.2 用法示例
例30_qgridlayout,网格布局(难度:简单),使用几个按钮,将他们设置为网格布局,同时设置它们的行、列比例系数(拉伸因子),以及设置它们的一些属性。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QGridLayout >
6 # include < QPushButton >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15 private:
	16
	17      /* 声明widget窗口部件,用于容纳下面4个pushButton按钮*/
	18 QWidget * gWidget;
	19
	20      /* 声明QGridLayout对象*/
	21 QGridLayout * gridLayout;
	22
	23      /* 声明pushButton按钮数组*/
	24 QPushButton * pushButton[4];
	25
	26
};
27 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6               /* 设置位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9               /* 实例化*/
	10 gWidget = new QWidget( this );
	11              /* 设置gWidget居中央*/
	12 this->setCentralWidget( gWidget );
	13
	14 gridLayout = new QGridLayout();
	15              /* QList链表,字符串类型*/
	16 QList <QString> list;
	17 list << "按钮1" << "按钮2" << "按钮3" << "按钮4";
	18 for ( int i = 0; i < 4; i++ )
	{
		19 pushButton[i] = new QPushButton();
		20 pushButton[i]->setText( list[i] );
		21      /* 设置最小宽度与高度*/
		22 pushButton[i]->setMinimumSize( 100, 30 );
		23      /* 自动调整按钮的大小*/
		24 pushButton[i]->setSizePolicy(
			25 QSizePolicy::Expanding,
			26 QSizePolicy::Expanding
			27 );
		28 switch ( i )
		{
			29 case 0:
			30 /* 将pushButton[0]添加至网格的坐标(0,0),下同*/
			31 gridLayout->addWidget( pushButton[i], 0, 0 );
			32 break;
			33 case 1:
			34 gridLayout->addWidget( pushButton[i], 0, 1 );
			35 break;
			36 case 2:
			37 gridLayout->addWidget( pushButton[i], 1, 0 );
			38 break;
			39 case 3:
			40 gridLayout->addWidget( pushButton[i], 1, 1 );
			41 break;
			42 default:
			43 break;
			44
		}
		45
	}
	46      /* 设置第0行与第1行的行比例系数*/
	47 gridLayout->setRowStretch( 0, 2 );
	48 gridLayout->setRowStretch( 1, 3 );
	49
	50      /* 设置第0列与第1列的列比例系数*/
	51 gridLayout->setColumnStretch( 0, 1 );
	52 gridLayout->setColumnStretch( 1, 3 );
	53
	54      /* 将gridLayout设置到gWidget */
	55 gWidget->setLayout( gridLayout );
	56
}


57
58 MainWindow::~MainWindow()
59
{
	60
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。可以看到在gWidget 中添加了4 个按钮,因为设置了行、列的系数比(拉伸因子),所以看到的按钮是按系数比的比例显示。
在这里插入图片描述

QFormLayout

7.5.3.1 控件简介
QFormLayout 继承QLayout。QFormLayout 类管理输入小部件及其关联标签的表单。QFormLayout 是一个方便的布局类,它以两列的形式布局其子类。左列由标签组成,右列由“字段”小部件(QLineEdit(行编辑器)、QSpinBox(旋转框等))组成。通常使用setRowWrapPolicy(RowWrapPolicy policy)接口函数设置布局的换行策略进行布局等。
7.5.3.2 用法示例
例31_qformlayout,表单布局(难度:简单),将使用addRow(const QString &labelText,QWidget *field)来创建一个带有给定文本的QLabel 及QWidget 小部件,并且它们是伙伴关系。
简单的展示表单布局的使用。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 #include <QFormLayout>
6 #include <QLineEdit>
7
8 class MainWindow : public QMainWindow
9 {
10 Q_OBJECT
11
12 public:
13 MainWindow(QWidget *parent = nullptr);
14 ~MainWindow();
15 private:
16 /* widget对象*/
17 QWidget *fWidget;
18
19 /* 用于输入用户名*/
20 QLineEdit *userLineEdit;
21
22 /* 用于输入密码*/
23 QLineEdit *passwordLineEdit;
24
25 /* 声明QFormLayout对象*/
26 QFormLayout *formLayout;
27 };
28 #endif // MAINWINDOW_H

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置位置与大小*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化及设置位置与大小,下同*/
10 fWidget = new QWidget(this);
11 fWidget->setGeometry(250, 100, 300, 200);
12
13 userLineEdit = new QLineEdit();
14 passwordLineEdit = new QLineEdit();
15
16 formLayout = new QFormLayout();
17
18 /* 添加行*/
19 formLayout->addRow("用户名:", userLineEdit);
20 formLayout->addRow("密码:", passwordLineEdit);
21
22 /* 设置水平垂直间距*/
23 formLayout->setSpacing(10);
24
25 /* 设置布局外框的宽度*/
26 formLayout->setMargin(20);
27
28 /* 将formLayout布局到fWidget */
29 fWidget->setLayout(formLayout);
30 }
31
32 MainWindow::~MainWindow()
33 {
34 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。可以看到在fWidget 中添加了两行,同时设置了它们的间隔,与距边框的宽度。与QGirdLayout 布局比较,QFomLayout 布局比较适用于行与列比较少的布局格局。如果是多行多列的布局,应该使用QGirdLayout 布局。
在这里插入图片描述

空间间隔

空间间隔组(Spacers),如下图所示
在这里插入图片描述
(1)Horizontal Spacer:水平间隔
(2)Vertical Spacer:垂直间隔
QSpacerItem 继承QLayoutItem。QSpacerItem 类在布局中提供空白(空间间隔)。所以QSpacerItem 是在布局中使用的。它包含Horizontal Spacer(水平间隔)与Vertical Spacer(垂直间隔)。

QSpacerItem

7.6.1.1 控件简介
QSpacerItem 继承QLayoutItem。QSpacerItem 类在布局中提供空白(空间间隔)。所以QSpacerItem 是在布局中使用的。
7.6.1.2 用法示例
例32_qspaceritem,空间间隔(难度:一般),使用4 个按钮,在垂直布局添加垂直间隔与按钮1,在水平布局添加按钮2~4 与水平间隔。简单的展示空间间隔布局的使用方法。在程序运行结果分析了空间间隔部分。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述

在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QPushButton >
6 # include < QSpacerItem >
7 # include < QBoxLayout >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 按钮对象数组*/
	19 QPushButton * bt[4];
	20      /* 垂直间隔*/
	21 QSpacerItem * vSpacer;
	22      /* 水平间隔*/
	23 QSpacerItem * hSpacer;
	24      /* 声明一个widget用来存放布局的内容*/
	25 QWidget * widget;
	26      /* 主布局对象*/
	27 QHBoxLayout * mainLayout;
	28      /* 垂直布局对象*/
	29 QVBoxLayout * vBoxLayout;
	30      /* 水平布局对象*/
	31 QHBoxLayout * hBoxLayout;
	32
	33
};
34 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置主窗体显示位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9 widget = new QWidget( this );
	10      /* 居中widget */
	11 this->setCentralWidget( widget );
	12
	13      /* 实例化对象*/
	14 vSpacer = new QSpacerItem( 10, 10,
				      15 QSizePolicy::Minimum,
				      16 QSizePolicy::Expanding
				      17 );
	18 hSpacer = new QSpacerItem( 10, 10,
				      19 QSizePolicy::Expanding,
				      20 QSizePolicy::Minimum
				      21 );
	22
	23 vBoxLayout	= new QVBoxLayout();
	24 hBoxLayout	= new QHBoxLayout();
	25 mainLayout	= new QHBoxLayout();
	26
	27                      /* 在vBoxLayout添加垂直间隔*/
	28 vBoxLayout->addSpacerItem( vSpacer );
	29
	30 QList <QString>list;
	31                      /* 将字符串值插入list */
	32 list << "按钮1" << "按钮2" << "按钮3" << "按钮4";
	33                      /* 用一个循环实例化4个按钮*/
	34 for ( int i = 0; i < 4; i++ )
	{
		35 bt[i] = new QPushButton();
		36 bt[i]->setText( list[i] );
		37 if ( i == 0 )
		{
			38      /* 按钮1,设置为100*100 */
			39 bt[i]->setFixedSize( 100, 100 );
			40      /* 在vBoxLayout添加按钮1 */
			41 vBoxLayout->addWidget( bt[i] );
			42
		} else {
			43      /* 按钮2~4,设置为60*60 */
			44 bt[i]->setFixedSize( 60, 60 );
			45      /* 在hBoxLayout添加按钮2~4 */
			46 hBoxLayout->addWidget( bt[i] );
			47
		}
		48
	}
	49                      /* 在hBoxLayout添加水平间隔*/
	50 hBoxLayout->addSpacerItem( hSpacer );
	51
	52                      /* 在主布局里添加垂直布局*/
	53 mainLayout->addLayout( vBoxLayout );
	54                      /* 在主布局里添加水平布局*/
	55 mainLayout->addLayout( hBoxLayout );
	56
	57                      /* 设置部件间距*/
	58 mainLayout->setSpacing( 50 );
	59                      /* 将主布局设置为widget的布局*/
	60 widget->setLayout( mainLayout );
	61
	62
}


63
64 MainWindow::~MainWindow()
65
{
	66
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,在垂直布局里添加了垂直空间间隔与按钮1,在水平布局里添加了按钮2~4 与水平空间间隔。
在这里插入图片描述
图解如下:
在这里插入图片描述

容器

容器(Containers)
在这里插入图片描述
各个控件的名称依次解释如下。
(1)Group Box:组框
(2)Scroll Area:滚动区域
(3)Tool Box:工具箱
(4)Tab Widget:标签小部件
(5)Stacked WIdget:堆叠小部件
(6)Frame:帧
(7)Widget:小部件
(8)MDI Area:MDI 区域
(9)Dock Widget:停靠窗体部件
各种容器的解释如下:
QGroupBox 继承QWidget。QGroupBox 为构建分组框提供了支持。分组框通常带有一个边框和一个标题栏,作为容器部件来使用,在其中可以布置各种窗口部件。布局时可用作一组控件的容器,但是需要注意的是,内部通常使用布局控件(如QBoxLayout)进行布局。组框还提供键盘快捷方式,键盘快捷方式将键盘焦点移动到组框的一个子部件。
QScrollArea 继承QAbstractScrollArea。滚动区域用于在框架中显示子部件的内容。如果小部件超过框架的大小,视图就会出现滚动条,以便可以查看子小部件的整个区域。
QToolBox 继承QFrame。QToolBox 类提供了一列选项卡小部件项。工具箱是一个小部件,它显示一列选项卡在另一列的上面,当前项显示在当前选项卡的下面。每个选项卡在选项卡列中都有一个索引位置。选项卡的项是QWidget。
QTabWidget 继承QWidget。abWidget 类提供了一组选项卡(多页面)小部件。QTabWidget主要是用来分页显示的,每一页一个界面,众多界面公用一块区域,节省了界面大小,很方便的为用户显示更多的信息。
QStackedWidget 继承QFrame。QStackedWidget 类提供了一个小部件堆栈,其中一次只能看到一个小部件,与QQ 的设置面板类似。QStackedWidget 可用于创建类似于QTabWidget 提供的用户界面。它是构建在QStackedLayout 类之上的一个方便的布局小部件。常与QListWidget搭配使用,效果如下图,左边的是QListWidget 列表,右边的是QStackedWidget。他们一般与
信号槽连接,通过点击左边的QListWidget 列表,使用信号槽连接后,就可以让右边的QStackedWidget 显示不同的内容,每次显示一个widget 小部件。
QWidget 类是所有用户界面对象的基类(如QLabel 类继承于QFrame 类,而QFrame 类又继承于QWidget 类)。Widget 是用户界面的基本单元:它从窗口系统接收鼠标,键盘和其他事件,并在屏幕上绘制自己。每个Widget 都是矩形的,它们按照Z-order 进行排序。注:Z-order是重叠二维对象的顺序,例如堆叠窗口管理器中的窗口。典型的GUI 的特征之一是窗口可能重叠,使得一个窗口隐藏另一个窗口的一部分或全部。当两个窗口重叠时,它们的Z 顺序确定哪个窗口出现在另一个窗口的顶部。理解:术语"z-order"指沿着z 轴物体的顺序。三维坐标轴中x横轴,y 数轴,z 上下轴。可以将gui 窗口视为平行与显示平面的一系列平面。因此,窗口沿着z 轴堆叠。所以z-order 指定了窗口的前后顺序。就像您桌面上的一叠纸一样,每张纸是一个窗口,桌面是您的屏幕,最上面的窗口z 值最高。QWidget 不是一个抽象类,它可以用作其他Widget的容器,并很容易作为子类来创建定制Widget。它经常用于创建、放置和容纳其他的Widget窗口。由上可知,QWidget 一般用于容纳其他Widget 窗口,其属性和方法相当的多,对于初学
者,我们通常只用它来作可以容纳其他窗口的容器,还会用来接收鼠标,键盘和其他事件等。
QMdiArea 继承QAbstractScrollArea。QMdiArea 小部件提供一个显示MDI 窗口的区域。
QMdiArea 的功能本质上类似于MDI 窗口的窗口管理器。大多数复杂的程序,都使用MDI 框架,在Qt designer 中可以直接将控件MDI Area 拖入使用。
QDockWidget 继承QWidget。QDockWidget 类提供了一个小部件,可以停靠在QMainWindow 内,也可以作为桌面的顶级窗口浮动。QDockWidget 提供了停靠部件的概念,也称为工具面板或实用程序窗口。停靠窗口是放置在QMainWindow 中央窗口附近的停靠窗口部件区域中的辅助窗口。停靠窗口可以被移动到当前区域内,移动到新的区域,并由终端用户浮动(例如,不
停靠)。QDockWidget API 允许程序员限制dock widget 的移动、浮动和关闭能力,以及它们可以放置的区域。QDockWidget 的初始停靠区域有Qt.BottomDockWidgetArea(底部停靠)、Qt.LeftDockWidgetArea(左边停靠、Qt.RightDockWidgetArea(右边停靠)、Qt.TopDockWidgetArea(顶部停靠)和Qt.NoDockWidgetArea(不显示Widget)。
在前面某些小节里已经有使用过本小节的控件,例如QWidget 小部件。下面将上面列出的控件进行进一步的解释与运用。

QGroupBox

7.7.1.1 控件简介
QGroupBox 小部件提供一个带有标题的组框框架。一般与一组或者是同类型的部件一起使用。

用法示例
例33_qgroupbox,组框示例(难度:简单),使用3 个QRadioButton 单选框按钮,与QVBoxLayout(垂直布局)来展示组框的基本使用。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 #include <QRadioButton>
6 #include <QGroupBox>
7 #include <QVBoxLayout>
8
9 class MainWindow : public QMainWindow
10 {
11 Q_OBJECT
12
13 public:
14 MainWindow(QWidget *parent = nullptr);
15 ~MainWindow();
16
17 private:
18 /* 声明对象*/
19 QGroupBox *groupBox;
20 QVBoxLayout *vBoxLayout;
21 QRadioButton *radioButton[3];
22 };
23 #endif // MAINWINDOW_

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QList >
3
4 MainWindow::MainWindow( QWidget *parent )
5 : QMainWindow( parent )
	6
{
	7               /* 设置主窗体位置与大小*/
	8 this->setGeometry( 0, 0, 800, 480 );
	9               /* 以标题为“QGroupBox 示例”实例化groupBox对象*/
	10 groupBox = new QGroupBox( tr( "QGroupBox示例" ), this );
	11 groupBox->setGeometry( 300, 100, 300, 200 );
	12
	13 vBoxLayout = new QVBoxLayout();
	14
	15              /* 字符串链表*/
	16 QList <QString>list;
	17 list << "选项一" << "选项二" << "选项三";
	18 for ( int i = 0; i < 3; i++ )
	{
		19 radioButton[i] = new QRadioButton();
		20 radioButton[i]->setText( list[i] );
		21      /* 在vBoxLayout添加radioButton */
		22 vBoxLayout->addWidget( radioButton[i] );
		23
	}
	24              /* 添加一个伸缩量1 */
	25 vBoxLayout->addStretch( 1 );
	26              /* vBoxLayout布局设置为groupBox布局*/
	27 groupBox->setLayout( vBoxLayout );
	28
}


29
30 MainWindow::~MainWindow()
31
{
	32
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,可以看到radioButton 有规则的排布在groupBox 组框里面。
在这里插入图片描述

QScrollArea

7.7.2.1 控件简介
QScrollArea 类提供到另一个小部件的滚动视图。
7.7.2.2 用法示例
例34_qscrollarea 滚动视图(难度:简单),使用一个Label 标签,将Label 标签设置为一张图片,并把Label 标签放置于滚动区域内,此时图片应要大于滚动区域才会出现滚动条。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,并添加了一张资源图片(添加资源图片的步骤请参考7.1.4 小节),如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QScrollArea >
6 # include < QLabel >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 定义QScrollArea对象*/
	18 QScrollArea * scrollArea;
	19 QLabel * label;
	20
};
21 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6 this->setGeometry( 0, 0, 800, 480 );
	7
	8 scrollArea = new QScrollArea( this );
	9       /* 设置滚动区域为700*380 */
	10 scrollArea->setGeometry( 50, 50, 700, 380 );
	11
	12 label = new QLabel();
	13      /* label显示的lantingxu.png图片分辨率为1076*500 */
	14 QImage image( ":/images/lantingxu.png" );
	15 label->setPixmap( QPixmap::fromImage( image ) );
	16
	17 scrollArea->setWidget( label );
	18
	19
}


20
21 MainWindow::~MainWindow()
22
{
	23
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,由于图片的大小大于滚动区域的大小,所以在滚动区域出现了滚动条,可以拖动滚动条来查看这张图片其余部分。
在这里插入图片描述

QToolBox

7.7.3.1 控件简介
QToolBox(工具盒类)提供了一种列状的层叠窗体,中文译为工具箱,类似抽屉。
7.7.3.2 用法示例
例35_qtoolbox,QQ 好友面板之QToolBox(难度:简单),本例将使用到前面的知识QGroupBox 组框与QBoxLayout 布局管理。前面我们已经学过QGroupBox 组框和学过QBoxLayout。有了前面的基础,那么去理解本例就会快很多。
本例思路:使用6 个QToolButton 分成2 组,使用垂直布局将QToolButton 的2 组排布好,然后添加到2 组QGroupBox 组框,再把2 组QGroupBox 组框作为子项添加到QToolBox。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,并添加了几张资源图片(添加资源图片的步骤请参考7.1.4 小节),如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QToolBox >
6 # include < QGroupBox >
7 # include < QToolButton >
8 # include < QVBoxLayout >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19 /* 声明对象*/
	20 QToolBox * toolBox;
	21 QGroupBox * groupBox[2];
	22 QVBoxLayout * vBoxLayout[2];
	23 QToolButton * toolButton[6];
	24
	25
};
26 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6 this->setGeometry( 0, 0, 800, 480 );
	7
	8 toolBox = new QToolBox( this );
	9 toolBox->setGeometry( 300, 50, 200, 250 );
	10 /* 设置toolBox的样式,此处设置为30%不透明度的黑色*/
	11 toolBox->setStyleSheet( "QToolBox {background-color:rgba(0, 0, 0,
30%);}" );
	12
	13 for ( int i = 0; i < 2; i++ )
	{
		14 vBoxLayout[i]	= new QVBoxLayout();
		15 groupBox[i]		= new QGroupBox( this );
		16
	}
	17
	18      /* 字符串链表*/
	19 QList <QString>strList;
	20 strList << "李白" << "王照君" << "李元芳" << "程咬金" << "钟馗" << "上官婉儿";
	21
	22      /* 字符串图标链表*/
	23 QList <QString>iconsList;
	24 iconsList << ":/icons/libai" << ":/icons/wangzhaojun"
	25 << ":/icons/liyuanfang" << ":/icons/chengyaojin"
	26 << ":/icons/zhongkui" << ":/icons/shangguanwaner";
	27
	28 for ( int i = 0; i < 6; i++ )
	{
		29 toolButton[i] = new QToolButton();
		30              /* 设置toolButton图标*/
		31 toolButton[i]->setIcon( QIcon( iconsList[i] ) );
		32              /* 设置toolButton的文本*/
		33 toolButton[i]->setText( strList[i] );
		34              /* 设置toolButton的大小*/
		35 toolButton[i]->setFixedSize( 150, 40 );
		36              /* 设置toolButton的setToolButtonStyle的样式*/
		37 toolButton[i]->setToolButtonStyle(
			38 Qt::ToolButtonTextBesideIcon
			39 );
		40 if ( i < 3 )
		{
			41      /* 将toolButton添加到时垂直布局*/
			42 vBoxLayout[0]->addWidget( toolButton[i] );
			43      /* 添加一个伸缩量1 */
			44 vBoxLayout[0]->addStretch( 1 );
			45
		} else {
			46 vBoxLayout[1]->addWidget( toolButton[i] );
			47 vBoxLayout[1]->addStretch( 1 );
			48
		}
		49
	}
	50      /* 将垂直布局的内容添加到组框groupBox */
	51 groupBox[0]->setLayout( vBoxLayout[0] );
	52 groupBox[1]->setLayout( vBoxLayout[1] );
	53
	54      /* 将组框加入QToolBox里*/
	55 toolBox->addItem( groupBox[0], "我的好友" );
	56 toolBox->addItem( groupBox[1], "黑名单" );
	57
}


58
59 MainWindow::~MainWindow()
60
{
	61
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,本次使用QToolButool 作为QGroupBox 的子项,也可以使用其他QWidget 小部件,如QWidget 等。(注意本程序在linux 运行效果如下,若如在Windows 下,可能QToolBox 的显示样式不一样)。点击“我的好友”列表,则会出现好友列表,点击“黑名单”则会出现黑名单列表。
在这里插入图片描述

QTabWidget

7.7.4.1 控件简介
QTabWidget 继承QWidget,QTabWidget 类提供了一组选项卡(多页面)小部件。QTabWidget 主要是用来分页显示的,每一页一个界面,众多界面公用一块区域,节省了界面大小,很方便的为用户显示更多的信息。类似浏览器的多标签页面,所以这个控件在实际项目中也会经常用到。
7.7.4.2 用法示例
例36_qtabwidget,标题栏多页面切换(难度:简单),本例创建3 个页面,每个页面里有一个Label 标签部件,点击每个页面的选项卡则会切换到不同的页面上。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,并添加了几张资源图片(添加资源图片的步骤请参考7.1.4 小节),如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTableWidget >
6 # include < QHBoxLayout >
7 # include < QLabel >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* 声明对象*/
	19 QWidget * widget;
	20 QTabWidget * tabWidget;
	21 QHBoxLayout * hBoxLayout;
	22 QLabel * label[3];
	23
};
24 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6 this->setGeometry( 0, 0, 800, 480 );
	7
	8 widget = new QWidget( this );
	9       /* 居中*/
	10 this->setCentralWidget( widget );
	11
	12      /* 多页面小部件*/
	13 tabWidget = new QTabWidget();
	14
	15      /* 水平布局实例化*/
	16 hBoxLayout = new QHBoxLayout();
	17 QList <QString>strLabelList;
	18 strLabelList << "标签一" << "标签二" << "标签三";
	19
	20 QList <QString>strTabList;
	21 strTabList << "页面一" << "页面二" << "页面三";
	22
	23 QList <QString>iconList;
	24 iconList << ":/icons/icon1"
	25 << ":/icons/icon2"
	26 << ":/icons/icon3";
	27
	28 for ( int i = 0; i < 3; i++ )
	{
		29 label[i] = new QLabel();
		30      /* 设置标签文本*/
		31 label[i]->setText( strLabelList[i] );
		32      /* 标签对齐方式(居中)*/
		33 label[i]->setAlignment( Qt::AlignCenter );
		34      /* 添加页面*/
		35 tabWidget->addTab( label[i],
				      36 QIcon( iconList[i] ),
				      37 strTabList[i]
				      38 );
		39
	}
	40              /* 是否添加关闭按钮*/
	41              /* tabWidget->setTabsClosable(true); */
	42              /* 将tabWidget水平直排布*/
	43 hBoxLayout->addWidget( tabWidget );
	44              /* 将垂直布局设置到widget */
	45 widget->setLayout( hBoxLayout );
	46
}


47
48 MainWindow::~MainWindow()
49
{
	50
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,点击不同页面的选项卡则会切换到不同的页面上。本例还可拓展使用void setTabsClosable(bool closeable)函数在选项卡后加一个关闭按钮,再连接信号槽实现关闭页面的操作。本例就不再添加代码了,比较简单。
在这里插入图片描述

QStackedWidget

7.7.5.1 控件简介
QStackedWidget 继承QFrame。QStackedWidget 类提供了一个小部件堆栈,其中一次只能看到一个小部件,与QQ 的设置面板类似。
QStackedWidget 可用于创建类似于QTabWidget 提供的用户界面。它是构建在QStackedLayout 类之上的一个方便的布局小部件。常与QListWidget 搭配使用,效果如下图,左边的是QListWidget 列表,右边的是QStackedWidget。他们一般与信号槽连接,通过点击左边的QListWidget 列表,使用信号槽连接后,就可以让右边的QStackedWidget 显示不同的内容,每次显示一个widget 小部件。
在这里插入图片描述
用法示例
例37_qstackedwidget,列表栏多页面切换(难度:简单),本例创建3 个堆栈页面,每个页面里有一个Label 标签部件,点击每个列表的不同项则会切换到不同的页面上。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QStackedWidget >
6 # include < QHBoxLayout >
7 # include < QListWidget >
8 # include < QLabel >
9
10 class MainWindow : public QMainWindow
	11 {
	12 Q_OBJECT
	13
	14 public:
	15 MainWindow( QWidget *parent = nullptr );
	16 ~MainWindow();
	17
	18 private:
	19      /* widget小部件*/
	20 QWidget * widget;
	21      /* 水平布局*/
	22 QHBoxLayout * hBoxLayout;
	23      /* 列表视图*/
	24 QListWidget * listWidget;
	25      /* 堆栈窗口部件*/
	26 QStackedWidget * stackedWidget;
	27      /* 3个标签*/
	28 QLabel * label[3];
	29
	30
};
31 # endif      /* MAINWINDOW_H */
32

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6 this->setGeometry( 0, 0, 800, 480 );
	7
	8       /* widget小部件实例化*/
	9 widget = new QWidget( this );
	10
	11      /* 设置居中*/
	12 this->setCentralWidget( widget );
	13
	14      /* 垂直布局实例化*/
	15 hBoxLayout = new QHBoxLayout();
	16
	17      /* 堆栈部件实例化*/
	18 stackedWidget = new QStackedWidget();
	19
	20      /* 列表实例化*/
	21 listWidget = new QListWidget();
	22
	23 QList <QString>strListWidgetList;
	24 strListWidgetList << "窗口一" << "窗口二" << "窗口三";
	25
	26 for ( int i = 0; i < 3; i++ )
	{
		27 /* listWidget插入项*/
		28 listWidget->insertItem(
			29 i,
			30 strListWidgetList[i]
			31 );
		32
	}
	33
	34 QList <QString>strLabelList;
	35 strLabelList << "标签一" << "标签二" << "标签三";
	36
	37 for ( int i = 0; i < 3; i++ )
	{
		38 label[i] = new QLabel();
		39      /* 设置标签文本*/
		40 label[i]->setText( strLabelList[i] );
		41      /* 标签对齐方式(居中)*/
		42 label[i]->setAlignment( Qt::AlignCenter );
		43      /* 添加页面*/
		44 stackedWidget->addWidget( label[i] );
		45
	}
	46
	47              /* 设置列表的最大宽度*/
	48 listWidget->setMaximumWidth( 200 );
	49              /* 添加到水平布局*/
	50 hBoxLayout->addWidget( listWidget );
	51 hBoxLayout->addWidget( stackedWidget );
	52
	53              /* 将widget的布局设置成hboxLayout */
	54 widget->setLayout( hBoxLayout );
	55
	56              /* 利用listWidget的信号函数currentRowChanged()与
	                 * 57 * 槽函数setCurrentIndex(),进行信号与槽连接
	                 * 58 */
	59 connect( listWidget, SIGNAL( currentRowChanged( int ) ),
		    60 stackedWidget, SLOT( setCurrentIndex( int ) ) );
	61
}


62
63 MainWindow::~MainWindow()
64
{
	65
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,点击列表视图的不同的项会切换到不同的页面上。
在这里插入图片描述

QFrame

在7.3.5 小节已经举过例子。

QWidget

7.7.7.1 控件简介
QWidget 类是所有用户界面对象的基类(如QLabel 类继承于QFrame 类,而QFrame 类又继承于QWidget 类)。Widget 是用户界面的基本单元:它从窗口系统接收鼠标,键盘和其他事件,并在屏幕上绘制自己。每个Widget 都是矩形的,它们按照Z-order 进行排序。
注:Z-order 是重叠二维对象的顺序,例如堆叠窗口管理器中的窗口。典型的GUI 的特征之一是窗口可能重叠,使得一个窗口隐藏另一个窗口的一部分或全部。当两个窗口重叠时,它们的Z 顺序确定哪个窗口出现在另一个窗口的顶部。
理解:术语"z-order"指沿着z 轴物体的顺序。三维坐标轴中x 横轴,y 数轴,z 上下轴。可以将gui 窗口视为平行与显示平面的一系列平面。因此,窗口沿着z 轴堆叠。所以z-order 指定了窗口的前后顺序。就像您桌面上的一叠纸一样,每张纸是一个窗口,桌面是您的屏幕,最上面的窗口z 值最高。
QWidget 不是一个抽象类,它可以用作其他Widget 的容器,并很容易作为子类来创建定制Widget。它经常用于创建、放置和容纳其他的Widget 窗口。
上面这么多例子都有用到QWidget,如7.5.1 小节,请自行参考,没有具体例子可写,比较简单。

QMdiArea

7.7.8.1 控件简介
QMdiArea 继承QAbstractScrollArea。QMdiArea 小部件提供一个显示MDI 窗口的区域。
QMdiArea 的功能本质上类似于MDI 窗口的窗口管理器。大多数复杂的程序,都使用MDI 框架,在Qt designer 中可以直接将控件MDI Area 拖入使用。
7.7.8.2 用法示例
例38_qmdiarea,父子窗口(难度:简单),本例创建一个MDI Area 区域,使用一个按钮,每单击按钮时,就会在MDI Area 区域新建一个MdiSubWindow 窗口。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QMdiSubWindow >
6 # include < QMdiArea >
7 # include < QPushButton >
8
9 class MainWindow : public QMainWindow
	10 {
	11 Q_OBJECT
	12
	13 public:
	14 MainWindow( QWidget *parent = nullptr );
	15 ~MainWindow();
	16
	17 private:
	18      /* Mdi Area区域对象*/
	19 QMdiArea * mdiArea;
	20      /* MdiSubWindow子窗口对象*/
	21 QMdiSubWindow * newMdiSubWindow;
	22      /* 用作点击创建新的窗口*/
	23 QPushButton * pushButton;
	24
	25 private slots:
	26      /* 按钮槽函数*/
	27 void creat_newMdiSubWindow();


	28
	29
};
30 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置窗口的显示位置与大小*/
7 this->setGeometry(0, 0, 800, 480);
8 pushButton = new QPushButton("新建窗口", this);
9 pushButton->setGeometry(0, 30, 100, 30);
10
11 mdiArea = new QMdiArea(this);
12 /* 设置MDI Area区域大小*/
13 mdiArea->setGeometry(100, 30, 700, 430);
14 /* 连接信号槽*/
15 connect(pushButton, SIGNAL(clicked()),
16 this, SLOT(creat_newMdiSubWindow()));
17 }
18
19 void MainWindow::creat_newMdiSubWindow()
20 {
21 newMdiSubWindow = new QMdiSubWindow();
22 newMdiSubWindow->setWindowTitle("新建窗口");
23
24 /* 如果窗口设置了Qt::WA_DeleteOnClose 这个属性,
25 * 在窗口接受了关闭事件后,Qt会释放这个窗口所占用的资源
26 */
27 newMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
28
29 /* 添加子窗口*/
30 mdiArea->addSubWindow(newMdiSubWindow);
31 /* 显示窗口,不设置时为不显示*/
32 newMdiSubWindow->show();
33 /* 自适应窗口*/
34 newMdiSubWindow->sizePolicy();
35 /* 以级联的方式排列所有窗口*/
36 // mdiArea->cascadeSubWindows();
37 /* 以平铺方式排列所有窗口*/
38 mdiArea->tileSubWindows();
39 }
40
41 MainWindow::~MainWindow()
42 {
43 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下,当点击新建窗口按钮时,在MDI Area 区域里新建了一个窗口标题为“新建窗口”窗口,下图为点击多次新建窗口的效果。本例使用了一个按钮,进行了新建窗口操作,其他功能例如添加删除按钮等,读者可以自行添加。本文在新建窗口里的内容为空,newMdiSubWindow 可以使用setWidget(QWidget *widget)方法添加内容,如添加前面所学过的QLineEdit 等。
在这里插入图片描述

QDockWidget

7.7.9.1 控件简介
QDockWidget 继承QWidget。QDockWidget 类提供了一个小部件,可以停靠在QMainWindow内,也可以作为桌面的顶级窗口浮动。
QDockWidget 提供了停靠部件的概念,也称为工具面板或实用程序窗口。停靠窗口是放置在QMainWindow 中央窗口附近的停靠窗口部件区域中的辅助窗口。停靠窗口可以被移动到当前区域内,移动到新的区域,并由终端用户浮动(例如,不停靠)。QDockWidget API 允许程序员限制dock widget 的移动、浮动和关闭能力,以及它们可以放置的区域。QDockWidget 的初始停
靠区域有Qt.BottomDockWidgetArea(底部停靠)、Qt.LeftDockWidgetArea(左边停靠、;Qt.RightDockWidgetArea (右边停靠)、Qt.TopDockWidgetArea (顶部停靠)和Qt.NoDockWidgetArea(不显示Widget)。
7.7.9.2 用法示例
例39_qdockwidget,停靠窗口(难度:简单),本例创建一个停靠窗口,在停靠窗口里添加文本编辑框,并且把这个停靠窗口放置到QMainWindow 的顶部。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QDockWidget >
6 # include < QTextEdit >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* 停靠窗口部件*/
	18 QDockWidget * dockWidget;
	19      /* 文本编辑框*/
	20 QTextEdit * textEdit;
	21
	22
};
23 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置主窗体的显示的位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9       /* 实例化标题为停靠窗口*/
	10 dockWidget = new QDockWidget( "停靠窗口", this );
	11
	12      /* 实例化文本编辑框*/
	13 textEdit = new QTextEdit( dockWidget );
	14
	15 textEdit->setText( "这是一个测试" );
	16
	17      /* 停靠窗口添加文本编辑框*/
	18 dockWidget->setWidget( textEdit );
	19
	20      /* 放在主窗体的顶部*/
	21 this->addDockWidget( Qt::TopDockWidgetArea, dockWidget );
	22
}


23
24 MainWindow::~MainWindow()
25
{
	26
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。拖动停靠窗口可以移动到另一个位置,松手则停靠。
在这里插入图片描述

项目视图组(基于模型)

在这里插入图片描述
上图需要注意的是,在低版本的Qt,Column View 与Undo View 是没有封装成可视控件形
式在Qt Creator 中。
以上各个控件的解释如下:
(1)List View:清单视图
(2)Tree View:树形视图
(3)Table View:表视图
(4)Column View:列表视图
(5)Undo View:撤销列表视图
以下是各个控件的简介:
QListView 继承QAbstractItemView,被QListWidget 和QUndoView 继承。QListView 类提供模型上的列表或图标视图。QListView 以简单的非分层列表或图标集合的形式显示存储在模型中的项。该类用于提供以前由QListBox 和QIconView 类提供的列表和图标视图,但是使用了Qt 的模型/视图体系结构提供的更灵活的方法。QListView 是基于Model,而QListWidget 是基于Item,这是它们的本质区别。QListView 需要建模,所以减少了冗余的数据,程序效率高;而QListWidget 是一个升级版本的QListView(实质是封装好了model 的QListView),它已经自己为我们建立了一个数据存储模型(QListWidgetItem),操作方便,直接调用addItem 即可添加项目(ICON,文字)。
QTreeView 继承QAbstractItemView,被QTreeWidget 继承。QTreeView 类提供树视图的默认模型/视图实现。QTreeView 实现了模型项的树表示。该类用于提供以前由QListView 类提供的标准分层列表,但是使用了Qt 的模型/视图体系结构提供的更灵活的方法。
QTableView 继承QAbstractItemView,被QTableWidget 继承。QTableView 类提供了表视图的默认模型/视图实现。QTableView 实现了一个表视图,用于显示来自模型的项。该类用于提供以前由QTable 类提供的标准表,但使用Qt 的模型/视图体系结构提供的更灵活的方法。
QColumnView 继承QAbstractItemView。QColumnView 在许多QListViews 中显示一个模型,每个QListViews 对应树中的每个层次结构。这有时被称为级联列表。QColumnView 类是模型/视图类之一,是Qt 模型/视图框架的一部分。QColumnView 实现了由QAbstractItemView 类定义的接口,以允许它显示由派生自QAbstractItemModel 类的模型提供的数据。
QUndoView 继承QlistView。QUndoView 类显示QUndoStack 的内容。QUndoView 是一个QListView,它显示在撤销堆栈上推送的命令列表。总是选择最近执行的命令。选择不同的命令会导致调用QUndoStack::setIndex(),将文档的状态向后或向前滚动到新命令。可以使用setStack()显式地设置堆栈。或者,可以使用setGroup()来设置QUndoGroup 对象。当组的活动堆栈发生变化时,视图将自动更新自身。

QListView

7.8.1.1 控件简介
QListView 继承QAbstractItemView,被QListWidget 和QUndoView 继承。QListView 类提供模型上的列表或图标视图。QListView 以简单的非分层列表或图标集合的形式显示存储在模型中的项。该类用于提供以前由QListBox 和QIconView 类提供的列表和图标视图,但是使用了Qt 的模型/视图体系结构提供的更灵活的方法。QListView 是基于Model,而QListWidget 是基于Item,这是它们的本质区别。QListView 需要建模,所以减少了冗余的数据,程序效率高;
而QListWidget 是一个升级版本的QListView(实质是封装好了model 的QListView),它已经自己为我们建立了一个数据存储模型(QListWidgetItem),操作方便,直接调用addItem 即可添加项目(ICON,文字)。
QT 提供了一些现成的models 用于处理数据项(这些是Qt 处理数据模型的精华,如果用到Qt 数据模型,下面这些是经常要用到的):
(1)QStringListModel 用于存储简单的QString 列表。
(2)QStandardItemModel 管理复杂的树型结构数据项,每项都可以包含任意数据。
(3)QDirModel 提供本地文件系统中的文件与目录信息。
(4)QSqlQueryModel, QSqlTableModel,QSqlRelationTableModel 用来访问数据库。
7.8.1.2 用法示例
例40_qlistview,清单图(难度:简单)。使用一个ListView 控件,展示如何在列表中插入数据,其中表中的内容可编辑,可删除。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QListView >
6 # include < QStringListModel >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* QListView对象*/
	18 QListView * listView;
	19      /* 字符串模型对象*/
	20 QStringListModel * stringListModel;
	21
	22
};
23 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6       /* 设置主窗口位置与大小*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9       /* 实例化*/
	10 listView = new QListView( this );
	11      /* 将listView居中*/
	12 setCentralWidget( listView );
	13
	14 QStringList strList;
	15 strList << "高三(1)班" << "高三(2)班" << "高三(3)班";
	16
	17      /* 实例化,字符串模型*/
	18 stringListModel = new QStringListModel( strList );
	19
	20      /* 向表中插入一段数据*/
	21 listView->setModel( stringListModel );
	22      /* 设置为视图为图标模式*/
	23 listView->setViewMode( QListView::IconMode );
	24      /* 设置为不可拖动*/
	25 listView->setDragEnabled( false );
	26
}


27
28 MainWindow::~MainWindow()
29
{
	30
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。双击表格中的项,可修改表格的内容,同时也可以删除内容等。
在这里插入图片描述

QTreeView

7.8.2.1 控件简介
QTreeView 继承QAbstractItemView,被QTreeWidget 继承。QTreeView 类提供树视图的默认模型/视图实现。QTreeView 实现了模型项的树表示。该类用于提供以前由QListView 类提供的标准分层列表,但是使用了Qt 的模型/视图体系结构提供的更灵活的方法。
用法示例例41_qtreeview,仿word 标题(难度:简单)。要使一个QTreeView 能够显示数据,需要构造一个model 并设置QTreeView。Qt 提供了一些类型的Model,其中最常用的就是这个QStandardItemModel 类,一般可以满足大部分需求。另外,表头的内容也由这个model 管理,setHorizontalHeaderLabels 函数可以设置共有多少列、每列文字。一级标题直接使用appendRow
方法添加到model 上,次级标题则是添加到第一个父级标题上,依次构成父子关系树。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTreeView >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16 QTreeView * treeView;
	17
	18
};
19 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 # include < QStandardItemModel >
4 # include < QStandardItem >
5
6 MainWindow::MainWindow( QWidget *parent )
7 : QMainWindow( parent )
	8
{
	9       /* 设置窗口的位置与大小*/
	10 this->setGeometry( 0, 0, 800, 480 );
	11      /* 实例化QTreeView对象*/
	12 treeView = new QTreeView( this );
	13      /* 居中*/
	14 setCentralWidget( treeView );
	15
	16      /* 构建Model */
	17 QStandardItemModel * sdiModel = new QStandardItemModel( treeView );
	18 sdiModel->setHorizontalHeaderLabels(
		19 QStringList() << QStringLiteral( "标题" )
		20 << QStringLiteral( "名称" )
		21 );
	22
	23 for ( int i = 0; i < 5; i++ )
	{
		24              /* 一级标题*/
		25 QList<QStandardItem*> items1;
		26 QStandardItem * item1 =
			27 new QStandardItem( QString::number( i ) );
		28 QStandardItem * item2 =
			29 new QStandardItem( QStringLiteral( "一级标题" ) );
		30              /* 添加项一*/
		31 items1.append( item1 );
		32              /* 添加项二*/
		33 items1.append( item2 );
		34              /* appendRow方法添加到model上*/
		35 sdiModel->appendRow( items1 );
		36
		37 for ( int j = 0; j < 5; j++ )
		{
			38      /* 在一级标题后面插入二级标题*/
			39 QList<QStandardItem*> items2;
			40 QStandardItem * item3 =
				41 new QStandardItem( QString::number( j ) );
			42 QStandardItem * item4 =
				43 new QStandardItem( QStringLiteral( "二级标题" ) );
			44 items2.append( item3 );
			45 items2.append( item4 );
			46      /* 使用appendRow方法添加到item1上*/
			47 item1->appendRow( items2 );
			48
		}
		49
	}
	50                      /* 设置Model给treeView */
	51 treeView->setModel( sdiModel );
	52
}


53
54 MainWindow::~MainWindow()
55
{
	56
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。可以点击数字来展开二级标题。
在这里插入图片描述

QTableView

7.8.3.1 控件简介
QTableView 继承QAbstractItemView,被QTableWidget 继承。QTableView 类提供了表视图的默认模型/视图实现。QTableView 实现了一个表视图,用于显示来自模型的项。该类用于提供以前由QTable 类提供的标准表,但使用Qt 的模型/视图体系结构提供的更灵活的方法。
7.8.3.2 用法示例
例42_qtableview,表格视图(难度:简单)。要使一个QTableView 能够显示数据,需要构造一个model 并设置给QTableView。Qt 提供了一些类型的Model,其中最常用的就是这个QStandardItemModel 类,一般可以满足大部分需求。另外,表头的内容也由这个model 管理,setHorizontalHeaderLabels 函数可以设置共有多少列、每列文字。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTableView >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16 QTableView * tableView;
	17
};
18 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QStandardItemModel >
3 # include < QHeaderView >
4
5 MainWindow::MainWindow( QWidget *parent )
6 : QMainWindow( parent )
	7
{
	8       /* 设置窗口的位置与大小*/
	9 this->setGeometry( 0, 0, 800, 480 );
	10 tableView = new QTableView( this );
	11 setCentralWidget( tableView );
	12      /* 显示网格线*/
	13 tableView->setShowGrid( true );
	14
	15 QStandardItemModel * model	= new QStandardItemModel();
	16 QStringList labels		=
		17 QObject::tr( "语文,数学,英语" ).simplified().split( "," );
	18      /* 设置水平头标签*/
	19 model->setHorizontalHeaderLabels( labels );
	20
	21      /* item */
	22 QStandardItem * item = 0;
	23      /* model插入项内容*/
	24 for ( int i = 0; i < 5; i++ )
	{
		25 item = new QStandardItem( "80" );
		26 model->setItem( i, 0, item );
		27 item = new QStandardItem( "99" );
		28 model->setItem( i, 1, item );
		29 item = new QStandardItem( "100" );
		30 model->setItem( i, 2, item );
		31
	}
	32      /* 将model设置给tableView */
	33 tableView->setModel( model );
	34      /* 平均分列*/
	35 tableView->horizontalHeader()
	36->setSectionResizeMode( QHeaderView::Stretch );
	37      /* 平均分行*/
	38 tableView->verticalHeader()
	39->setSectionResizeMode( QHeaderView::Stretch );
	40
}


41
42 MainWindow::~MainWindow()
43 {
	44

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。建立了一个成绩表格。
在这里插入图片描述

QColumnView

7.8.4.1 控件简介
QColumnView 继承QAbstractItemView。QColumnView 在许多QListViews 中显示一个模型,每个QListViews 对应树中的每个层次结构。这有时被称为级联列表。QColumnView 类是模型/视图类之一,是Qt 模型/视图框架的一部分。QColumnView 实现了由QAbstractItemView 类定义的接口,以允许它显示由派生自QAbstractItemModel 类的模型提供的数据。
用法示例
例43_qcolumnview,收货地址(难度:简单)。使用一个QColumnView,向其插入多级QStandardItem。这样就可以模拟成一个多级联的视图。与我们在像某宝,某东里填写的收货地址十分类似。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QColumnView >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16 QColumnView * columnView;
	17
};
18 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QStandardItem >
3
4 MainWindow::MainWindow( QWidget *parent )
5 : QMainWindow( parent )
	6
{
	7       /* 设置主窗体显示位置与大小*/
	8 this->setGeometry( 0, 0, 800, 480 );
	9 QStandardItemModel * model = new QStandardItemModel;
	10
	11      /* 省份*/
	12 QStandardItem * province = new QStandardItem( "广东省" );
	13
	14      /* 城市*/
	15 QStandardItem * city1	= new QStandardItem( "茂名市" );
	16 QStandardItem * city2	= new QStandardItem( "中山市" );
	17
	18      /* 添加城市到省份下*/
	19 province->appendRow( city1 );
	20 province->appendRow( city2 );
	21
	22 QStandardItem * town1	= new QStandardItem( "电白镇" );
	23 QStandardItem * town2	= new QStandardItem( "南头镇" );
	24
	25      /* 添加城镇到城市下*/
	26 city1->appendRow( town1 );
	27 city2->appendRow( town2 );
	28
	29 columnView = new QColumnView;
	30
	31      /* 建立model */
	32 model->appendRow( province );
	33
	34      /* 设置model */
	35 columnView->setModel( model );
	36
	37      /* 设置居中*/
	38 setCentralWidget( columnView );
	39
}


40
41 MainWindow::~MainWindow()
42
{
	43
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。当点击省份出现城市,点击城市出现城镇。
在这里插入图片描述

QUndoView

控件简介
QUndoView 继承QlistView。QUndoView 类显示QUndoStack 的内容。QUndoView 是一个QListView,它显示在撤销堆栈上推送的命令列表。总是选择最近执行的命令。选择不同的命令会导致调用QUndoStack::setIndex(),将文档的状态向后或向前滚动到新命令。可以使用setStack()显式地设置堆栈。或者,可以使用setGroup()来设置QUndoGroup 对象。当组的活动堆栈发生
变化时,视图将自动更新自身。
7.8.5.2 用法示例
例44_qundoview,仿PS 历史记录(难度:一般)。如果大家学习过PS,都知道PS 里有个历史记录面板,点击就会撤回到历史记录的步骤。例子其实也可以参考Qt 官方提供的例子“UndoFramework Example”。但是官方的例子过于复杂,整个理解下来需要花费大量时间。于是笔者写一个仿PS 历史记录的例子来加深大家对QUndoView 的理解。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。同时添加了两个新建文件》点击新建,选择C++》C++ Source File 命名command.h 和command.cpp 文件,用于重写QUndoCommand。项目新建完成,如下图。
在这里插入图片描述
在头文件“command.h”具体代码如下。

1 # ifndef COMMAND_H
2 # define COMMAND_H
3
4 # include < QUndoCommand >
5 # include < QObject >
6
7 class addCommand : public QUndoCommand
	8 {
	9 public:
	10 addCommand( int *value, QUndoCommand* parent = 0 );
	11 ~addCommand();
	12
	13 /* 重写重做与撤回方法*/
	14 void redo() override;


	15 void undo() override;


	16
	17 private:
	18      /* 新的count */
	19 int *new_count;
	20
	21      /* 旧的count */
	22 int old_count;
	23
};
24
25 # endif      /* COMMAND_H */

在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QUndoView >
6 # include < QUndoStack >
7 # include < QHBoxLayout >
8 # include < QVBoxLayout >
9 # include < QPushButton >
10 # include < QLabel >
11 # include < command.h >
12
13 class MainWindow : public QMainWindow
	14 {
	15 Q_OBJECT
	16
	17 public:
	18 MainWindow( QWidget *parent = nullptr );
	19 ~MainWindow();
	20
	21 private:
	22      /* 水平布局*/
	23 QHBoxLayout * hLayout;
	24      /* 水平布局*/
	25 QVBoxLayout * vLayout;
	26      /* 用于容纳hLayout布局*/
	27 QWidget * mainWidget;
	28      /* 容器作用QWidget,用于容纳标签与按钮*/
	29 QWidget * widget;
	30      /* 存放QUndoCommand命令的栈*/
	31 QUndoStack * undoStack;
	32      /* 历史记录面板*/
	33 QUndoView * undoView;
	34      /* 用于显示计算结果*/
	35 QLabel * label;
	36      /* 按钮*/
	37 QPushButton * pushButton;
	38      /* 计算结果*/
	39 int count;
	40
	41 private slots:
	42 void pushButtonClieked();


	43 void showCountValue( int );


	44
};
45 # endif /* MAINWINDOW_H */

在源文件“command.cpp”具体代码如下。

1 # include "command.h"
2 # include < QDebug >
3
4 addCommand::addCommand( int *value, QUndoCommand *parent )
5
{
	6       /* 使用Q_UNUSED,避免未使用的数据类型*/
	7 Q_UNUSED( parent );
	8
	9       /* undoView显示的操作信息*/
	10 setText( "进行了加1操作" );
	11
	12      /* value的地址赋值给new_count */
	13 new_count = value;
	14
	15      /* 让构造函数传过来的*new_count的值赋值给old_count */
	16 old_count = *new_count;
	17
}


18
19              /* 执行stack push时或者重做操作时会自动调用*/
20 void addCommand::redo()
21
{
	22      /* 重新赋值给new_count */
	23 * new_count = old_count;
	24
	25      /* 打印出*new_count的值*/
	26 qDebug() << "redo:" << *new_count << endl;
	27
}


28
29              /* 回撤操作时执行*/
30 void addCommand::undo()
31
{
	32      /* 回撤操作每次应减一*/
	33 (*new_count)--;
	34
	35      /* 打印出*new_count的值*/
	36 qDebug() << "undo:" << *new_count << endl;
	37
}


38
39 addCommand::~addCommand()
40
{
	41
	42
}



在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2 # include < QDebug >
3
4 MainWindow::MainWindow( QWidget *parent )
5 : QMainWindow( parent )
	6
{
	7       /* 设置主窗体显示的位置与大小*/
	8 this->setGeometry( 0, 0, 800, 480 );
	9
	10      /* 实例一个水平布局,用于左侧按钮区域与右侧历史记录面板*/
	11 hLayout = new QHBoxLayout();
	12
	13      /* 实例一个水平布局,用于左侧标签与按钮*/
	14 vLayout = new QVBoxLayout();
	15
	16      /* 主Widget, 因为MainWindow自带一个布局,
	         * 17 * 我们要新建一个Widget容纳新布局
	         * 18 */
	19 mainWidget = new QWidget();
	20
	21      /* 用于存放命令行栈*/
	22 undoStack = new QUndoStack( this );
	23
	24      /* 用于容纳左侧标签与按钮布局*/
	25 widget = new QWidget();
	26
	27      /* 历史记录面板实例化*/
	28 undoView = new QUndoView( undoStack );
	29
	30      /* 实例一个按钮,用于加一操作*/
	31 pushButton = new QPushButton();
	32
	33      /* 标签,用于显示计算结果*/
	34 label = new QLabel();
	35
	36      /* 设置widget的大小*/
	37 widget->setMinimumSize( 400, 480 );
	38
	39      /* 将两个widget添加到水平布局*/
	40 hLayout->addWidget( widget );
	41 hLayout->addWidget( undoView );
	42
	43      /* 初始化count的值*/
	44 count = 0;
	45
	46      /* 显示初始化计算结果*/
	47 label->setText( "计算结果:" + QString::number( count ) );
	48 label->setAlignment( Qt::AlignCenter );
	49
	50      /* 左侧布局*/
	51 vLayout->addWidget( label );
	52 vLayout->addWidget( pushButton );
	53
	54      /* 左侧布局控件的高度设置*/
	55 label->setMaximumHeight( this->height() / 5 );
	56 pushButton->setMaximumHeight( this->height() / 5 );
	57
	58      /* 按钮文件设置*/
	59 pushButton->setText( "加1" );
	60
	61      /* 设置widget的布局为vLayout */
	62 widget->setLayout( vLayout );
	63
	64      /* 将主窗体的布局设置为hLayout */
	65 mainWidget->setLayout( hLayout );
	66
	67      /* 设置mainWidget为主窗体的居中widget */
	68 this->setCentralWidget( mainWidget );
	69
	70      /* 信号槽连接,按钮点击,执行加一操作*/
	71 connect( pushButton, SIGNAL( clicked() ), this,
		    72 SLOT( pushButtonClieked() ) );
	73
	74      /* 信号槽连接,历史记录项index发生变化,显示count大小*/
	75 connect( undoStack, SIGNAL( indexChanged( int ) ),
		    76 this, SLOT( showCountValue( int ) ) );
	77
}


78
79              /* 入栈操作会自动调用addCommand的redo */
80 void MainWindow::pushButtonClieked()
81
{
	82      /* 变量值加一*/
	83 count++;
	84
	85      /* value指向count的地址*/
	86 int *value = &count;
	87
	88      /* 用重写的addCommand类实例化*/
	89 QUndoCommand * add = new addCommand( value );
	90
	91      /* 入栈*/
	92 undoStack->push( add );
	93
}


94
95 void MainWindow::showCountValue( int )
96
{
	97 /* 标签用于显示计算结果*/
	98 label->setText( "计算结果:" + QString::number( count ) );
	99
}


100
101 MainWindow::~MainWindow()
102
{
	103
	104
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。点击“加1”按钮,计算结果将加1,用方向键或者鼠标进行选择右边的历史记录面板将进行重做或者回撤操作,同时应用程序输出窗口打印出debug 信息,计算结果也将回到该步时的计算结果。
本例总结:使用数学运算加一的方法,简单的说明了QUndoView 的使用。如果大家想到有好QUndoView 的使用情景就可以模仿本例再深度优化或者进行知识拓展。
在这里插入图片描述

项目控件组(基于项)

在这里插入图片描述
在上一小节学习过视图组,下面学习控件组。仔细观察视图组里的某几个控件与控件组的控件名字相似。以QListWidget 为例,QListWidget 就是继承QListView。QListView 是基于模型的,而QListWidget 是基于项的。两种控件在不同的场合可以酌情选择使用!一般处理大数据使用基于模型的多。视图组与控件组的控件在Qt 里展示数据时是会经常使用的!大家要掌握它们的使用方法。
以上各个控件的解释如下:
(1)List Widget:清单控件
(2)TreeWidget:树形控件
(3)Table Widget:表控件
以下是各个控件的简介:
QListWidget 继承QListView。QListWidget 类提供了一个基于项的列表小部件。QListWidget 是一个便捷的类,它提供了一个类似于QListView 提供的列表视图,但是提供了一个用于添加和删除项目的基于项目的经典接口。QListWidget 使用内部模型来管理列表中的每个QListWidgetItem。QListView 是基于model 的,需要自己来建模(例如建立QStringListModel、QSqlTableModel 等),保存数据,这样就大大降低了数据冗余,提高了程序的效率,但是需要我们对数据建模有一定了解,而QListWidget 是一个升级版本的QListView,它已经自己为我们建立了一个数据存储模型(QListWidgetItem),操作方便,直接调用addItem 即可添加项目(ICON,文字)。
QTreeWidget 继承QTreeView。QTreeWidget 类提供了一个使用预定义树模型的树视图。
QTreeWidget 类是一个便捷的类,它提供了一个标准的树小部件,具有一个类似于qt3 中的QListView 类所使用的基于项目的经典接口。该类基于Qt 的模型/视图体系结构,并使用默认模型来保存项,每个项都是QTreeWidgetItem。
QTableWidget 继承QTableView。QTableWidget 类提供了一个带有默认模型的基于项的表视图。表小部件为应用程序提供标准的表显示工具。QTableWidget 中的项由QTableWidgetItem 提供。

QListWidget

7.9.1.1 控件简介
QListWidget 继承QListView。QListWidget 类提供了一个基于项的列表小部件。QListWidget 是一个便捷的类,它提供了一个类似于QListView(下一小节将讲到)提供的列表视图,但是提供了一个用于添加和删除项目的基于项目的经典接口。QListWidget 使用内部模型来管理列表中的每个QListWidgetItem。
7.9.1.2 用法示例
例45_qlistwidget,添加“歌曲”(难度:简单)。本例使用一个QListWidget 以及一个按钮,当单击按钮时,就会调用系统打开文件窗口,过滤mp3 后缀的文件(本例使用touch 指令创建2 个mp3 后缀的文件,并不是真正的歌曲,在终端输入指令为touch 0.mp3 1.mp3,本例在项目下已经创建了两个以mp3 为后缀的文件),当打开系统文件选择框时,就会选择这两个mp3 文件作为QListWidget 的项添加到QListWidget 的窗口中。(PS:我们写音乐播放器就要用到这种操作—打开歌曲。实际本例就是一个打开歌曲的代码部分。)
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QListWidget >
6 # include < QPushButton >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17 /* 声明对象*/
	18 QListWidget * listWidget;
	19 QPushButton * pushButton;
	20
	21 private slots:
	22 void pushButtonClicked();


	23
	24
};
25 # endif /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 #include "mainwindow.h"
2 #include "QFileDialog"
3
4 MainWindow::MainWindow(QWidget *parent)
5 : QMainWindow(parent)
6 {
7 /* 设置主窗口的显示位置与大小*/
8 this->setGeometry(0, 0, 800, 480);
9
10 listWidget = new QListWidget(this);
11
12 /* 设置listWidget的大小*/
13 listWidget->setGeometry(0, 0, 480, 480);
14
15 listWidget->addItem("请单击右边的添加项添加内容");
16
17 pushButton = new QPushButton(this);
18
19 /* 设置pushButton的位置与大小*/
20 pushButton->setGeometry(540, 200, 200, 100);
21 pushButton->setText("添加项");
22
23 /* 信号与槽连接*/
24 connect(pushButton, SIGNAL(clicked()),
25 this, SLOT(pushButtonClicked()));
26 }
27
28 void MainWindow::pushButtonClicked()
29 {
30 /* 调用系统打开文件窗口,设置窗口标题为“打开文件”,过滤文件名*/
31 QString fileName = QFileDialog::getOpenFileName(
32 this,tr("添加项"),"",
33 tr("Files(*.mp3)")
34 );
35
36 /* 判断是否选中打开mp3文件*/
37 if (fileName != NULL)
38 /* 添加项到列表中*/
39 listWidget->addItem(fileName);
40 }
41
42 MainWindow::~MainWindow()
43 {
44 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。当点击添加项按钮时出现系统选择文件的对话框,系统打开文件时会过滤mp3 后缀的文件,点击后缀为mp3 的文件,双击或者选择后再点击右上角的“Open”的打开来把这个文件添加到左边的QListWidget 列表中。读者可以模仿这个示例,还可以添加删除项的按钮,或者删除全部按钮等,酷狗音乐播放器的的歌单与此类似。后续继续学习如何播放音乐,与此结合,就可以做出一款音乐播放器了。
在这里插入图片描述
在这里插入图片描述

QTreeWidget

7.9.2.1 控件简介
QTreeWidget 继承QTreeView。QTreeWidget 类提供了一个使用预定义树模型的树视图。
QTreeWidget 类是一个便捷的类,它提供了一个标准的树小部件,具有一个类似于qt3 中的QListView 类所使用的基于项目的经典接口。该类基于Qt 的模型/视图体系结构,并使用默认模型来保存项,每个项都是QTreeWidgetItem。
7.9.2.2 用法示例
例46_qtreewidget,群发信息(难度:一般),本例使用一个TreeWidget,模拟成一个飞信联系人分组,通过选中组内联系人来“群发”信息。实际并不是真正做一个群发信息的飞信,只是模拟飞信群发信息时选择联系人的场景,通过例子来熟悉QTreeWidget 的使用。本例相对前面的例子稍长,出现了树节点与子节点的概念。本例的思路:当选中顶层的树形节点时,子节点全部被选中;当取消选择顶层树形节点时,子节点原来选中的状态将全部取消;当不完全选中子节点时,树节点显示为半选状态。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTreeWidget >
6 # include < QTreeWidgetItem >
7
8 class MainWindow : public QMainWindow
	9 {
	10 Q_OBJECT
	11
	12 public:
	13 MainWindow( QWidget *parent = nullptr );
	14 ~MainWindow();
	15
	16 private:
	17      /* QTreeWidget对象*/
	18 QTreeWidget * treeWidget;
	19      /* 顶层树节点*/
	20 QTreeWidgetItem * parentItem;
	21      /* 声明三个子节点*/
	22 QTreeWidgetItem * subItem[3];
	23
	24      /* 子节点处理函数*/
	25 void updateParentItem( QTreeWidgetItem* );


	26
	27 private slots:
	28      /* 槽函数*/
	29 void treeItemChanged( QTreeWidgetItem*, int );


	30
	31
};
32 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置主窗体大小*/
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 实例化*/
10 treeWidget = new QTreeWidget(this);
11
12 /* 居中*/
13 setCentralWidget(treeWidget);
14
15 /* 清空列表*/
16 treeWidget->clear();
17
18 /* 实例化顶层树节点*/
19 parentItem = new QTreeWidgetItem(treeWidget);
20 parentItem->setText(0, "同事");
21
22 parentItem->setFlags(
23 Qt::ItemIsUserCheckable
24 | Qt::ItemIsEnabled
25 | Qt::ItemIsSelectable
26 );
27 /* 树节点设置为未选中*/
28 parentItem->setCheckState(0, Qt::Unchecked);
29
30 /* 字符串链表*/
31 QList <QString> strList;
32 strList<<"关羽"<<"刘备"<<"张飞";
33
34 for (int i = 0; i < 3; i++){
35 /* 实例化子节点*/
36 subItem[i] = new QTreeWidgetItem(parentItem);
37 /* 设置子节点的文本,参数0代表第0列*/
38 subItem[i]->setText(0, strList[i]);
39 /* 设置子节点的属性为用户可选、项开启、项可选*/
40 subItem[i]->setFlags(
41 Qt::ItemIsUserCheckable
42 | Qt::ItemIsEnabled
43 | Qt::ItemIsSelectable
44 );
45 /* 设置子节点的状态为未选中*/
46 subItem[i]->setCheckState(0,Qt::Unchecked);
47 }
48 /* 信号槽连接*/
49 connect(treeWidget,SIGNAL(itemChanged(QTreeWidgetItem* , int)),
50 this, SLOT(treeItemChanged(QTreeWidgetItem* , int)));
51
52 }
53
54 /* 更新树节点函数*/
55 void MainWindow::updateParentItem(QTreeWidgetItem *item)
56 {
57 /* 获取子节点的父节点(树节点)*/
58 QTreeWidgetItem* parent = item->parent();
59 if(parent == NULL){
60 return;
61 }
62 /* 初始化选中的数目为0,下面根据selectCount来判断树节点的状态*/
63 int selectCount = 0;
64 /* 获取树节点的子节点总数*/
65 int childCount = parent->childCount();
66 /* 循环判断子节点的状态*/
67 for(int i = 0; i < childCount; i ++){
68 QTreeWidgetItem* childItem =parent->child(i);
69 /* 判断当前子节点的状是否为选中状态,如果是,则加一*/
70 if(childItem->checkState(0) == Qt::Checked) {
71 selectCount ++;
72 }
73 }
74 /* 根据selectCount来判断树节点的状态*/
75 /* 当选中的子节点小于或等于0时,则为设置树节点为未选中状态*/
76 if (selectCount <= 0) {
77 /* 设置树节点为未选中状态*/
78 parent->setCheckState(0, Qt::Unchecked);
79 /* 部分选中时,树节点为半选状态*/
80 } else if (selectCount > 0 && selectCount < childCount) {
81 /* 设置为半选状态*/
82 parent->setCheckState(0, Qt::PartiallyChecked);
83 /* 子节点全选时*/
84 } else if (selectCount == childCount){
85 /* 设置为树节点为选中状态*/
86 parent->setCheckState(0, Qt::Checked);
87 }
88 }
89
90 void MainWindow::treeItemChanged(QTreeWidgetItem *item, int)
91 {
92 /* 获取子节点总数*/
93 int count = item->childCount();
94
95 /* 若顶层树节点选中*/
96 if(Qt::Checked == item->checkState(0) ) {
97 /* 若选中的项是树节点,count会大于0,否则选中的项是子节点*/
98 if (count > 0) {
99 for (int i = 0; i < count; i++) {
100 /* 子节点全选*/
101 item->child(i)->setCheckState(0, Qt::Checked);
102 }
103 } else {
104 /* 子节点处理*/
105 updateParentItem(item);
106 }
107 /* 若顶层树节点取消选中时*/
108 } else if (Qt::Unchecked == item->checkState(0)) {
109 if (count > 0){
110 /* 若选中的项是树节点,count会大于0,否则选中的项是子节点*/
111 for (int i = 0; i < count; i++) {
112 /* 子节点全不选*/
113 item->child(i)->setCheckState(0, Qt::Unchecked);
114 }
115 } else {
116 /* 子节点处理*/
117 updateParentItem(item);
118 }
119 }
120 }
121
122 MainWindow::~MainWindow()
123 {
124 }

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。下图为全选时的状态,好比要群发信息时全选联系人的场景。当选中树节点同事时,子节点(关羽、刘备、张飞)将全选;当树节点同事未选中时,子节点(关羽、刘备、张飞)的状态为未选中;当子节点(关羽、刘备、张飞)选中且不全选时,树节点同事的状态将为半选状态。
在这里插入图片描述

QTableWidget

7.9.3.1 控件简介
QTableWidget 继承QTableView。QTableWidget 类提供了一个带有默认模型的基于项的表视图。表小部件为应用程序提供标准的表显示工具。QTableWidget 中的项由QTableWidgetItem 提供。
7.9.3.2 用法示例
例47_qtablewidget,TabelWidget 表格(难度:简单),本例使用一个TableWidget,绘制一个表格,同时修改项的标题,在表格里可以直接通过双击进行编辑项里的内容,也可以删除项里的内容等。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow 类即可。项目新建完成,如下图。
在这里插入图片描述
在头文件“mainwindow.h”具体代码如下。

1 # ifndef MAINWINDOW_H
2 # define MAINWINDOW_H
3
4 # include < QMainWindow >
5 # include < QTableWidget >
6
7 class MainWindow : public QMainWindow
	8 {
	9 Q_OBJECT
	10
	11 public:
	12 MainWindow( QWidget *parent = nullptr );
	13 ~MainWindow();
	14
	15 private:
	16      /* QTabelWidget表格*/
	17 QTableWidget * tableWidget;
	18
	19      /* QTabelWidgetItem表格数据(项)*/
	20 QTableWidgetItem * tableWidgetItem[4];
	21
	22
};
23 # endif      /* MAINWINDOW_H */

在源文件“mainwindow.cpp”具体代码如下。

1 # include "mainwindow.h"
2
3 MainWindow::MainWindow( QWidget *parent )
4 : QMainWindow( parent )
	5
{
	6               /* 设置主窗体的大小与位置*/
	7 this->setGeometry( 0, 0, 800, 480 );
	8
	9               /* 实例化*/
	10 tableWidget = new QTableWidget( this );
	11              /* 设置tableWidget表居中*/
	12 setCentralWidget( tableWidget );
	13              /* 设置列数*/
	14 tableWidget->setColumnCount( 2 );
	15              /* 设置行数*/
	16 tableWidget->setRowCount( 2 );
	17              /* 使用标签设置水平标题标签*/
	18 tableWidget->setHorizontalHeaderLabels(
		19 QStringList() << "姓名" << "性别"
		20 );
	21
	22              /* 字符串类型链表*/
	23 QList <QString> strList;
	24 strList << "小明" << "小红" << "男" << "女";
	25
	26 for ( int i = 0; i < 4; i++ )
	{
		27      /* 实例化*/
		28 tableWidgetItem[i] = new QTableWidgetItem( strList[i] );
		29      /* 设置文本居中对齐*/
		30 tableWidgetItem[i]->setTextAlignment( Qt::AlignCenter );
		31
	}
	32              /* 插入数据,表的index就是一个二维数组数据*/
	33 tableWidget->setItem( 0, 0, tableWidgetItem[0] );
	34 tableWidget->setItem( 1, 0, tableWidgetItem[1] );
	35 tableWidget->setItem( 0, 1, tableWidgetItem[2] );
	36 tableWidget->setItem( 1, 1, tableWidgetItem[3] );
	37
	38
}


39
40 MainWindow::~MainWindow()
41
{
	42
}



在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。

1 # include "mainwindow.h"
2
3 # include < QApplication >
4
5 int main( int argc, char *argv[] )
6
{
	7 QApplication a( argc, argv );
	8 MainWindow w;
	9 w.show();
	10 return(a.exec() );
	11
}



运行效果
程序编译运行的结果如下。双击表格中的项,可修改表格的内容,同时也可以删除内容等。
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行稳方能走远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值