1.QLabe标签
1.1基本属性
QLabel用于显示图片或文字,需要注意的是,QLabel不能与用户交互(不能点击),只能展示使用,因此没有合适的信号函数。

1.2 添加资源库
把图片导入到下项目中,成为项目资源,直接使用Qt的虚拟路径导入项目图片,可以在任何环境中使用这些资源图片了。
Qt支持以下几种常见的图片格式:
.jpg(不包含透明度)、png(包含透明度)、gif等等
注意导入的图片不能特别大(分辨率过高或者文件体积过大),因为图片的操作非常消耗资源。
下面是导入图片的操作步骤:
1.把命名好的图片放置到项目的工作目录中
2.在QtCreator中选中项目名称,鼠标右键点击添加新文件。
3.在弹出的窗口中,按照下图所示进行操作

4.在弹出的窗口中给资源文件命名,例如res

5.在项目管理界面,点击直接完成,可以看到项目中多了一个.qrc格式的资源文件。

6.选中qrc文件,点击前缀,可以给资源文件新建一个虚拟路径。

7.选中qrc文件,点击添加文件,可以导入图片到项目中成为资源

8.导入成功后,可以在qrc文件中看到导入成功的图片

1.3使用资源库
1.点击小锤子,重新构建项目。这样就可以在Designer中使用了。



1.4使用代码添加图片
1.可以通过代码来加载图片,已经修建图片尺寸等。

2.如果要通过代码来加载图片,还需要使用include<QPixmap>头文件,图片类头文件。
3.创建一个图片类对象
cpp
```cpp
// 图片类构造函数
// 参数1:图片类资源路径
// 参数2:样板格式,使用默认即可
// 参数3:图片颜色格式,使用默认即可
QPixmap::QPixmap(const QString & fileName, const char * format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor)
```
4.当前已将创建了图片类对象,但是还需要进行缩放,指定图片的输出模式。
cpp
```cpp
// 缩放函数
// 参数1:宽度
// 参数2:高度
// 参数3:三种缩放模式, 是一个枚举类型
// 参数4:以速度优先还是以质量优先。两种模式,默认是以速度优先,也是一个枚举值
// 返回值:转换后的QPixmap对象
QPixmap QPixmap::scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation) const
```
dialog.h
cpp
```cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPixmap>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
```
dialog.cpp
cpp
```cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
// 创建QPixmap栈内存对象
QPixmap pic(":/new/prefix1/g.jpg");
// 图片缩放
pic = pic.scaled(ui->label->width(),ui->label->height(),
Qt::KeepAspectRatio,Qt::SmoothTransformation);
// 显式图片
ui->label->setPixmap(pic);
}
Dialog::~Dialog()
{
delete ui;
}
```
2.QLineEdit单行文本输入框
QLineEdit用于输入一个单行文本。

dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QDebug>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void btnClickedSlot();
};
#endif // DIALOG_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),
this,SLOT(btnClickedSlot()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::btnClickedSlot()
{
QString text = ui->lineEdit->text();
qDebug () << "第一个QLineEdit的内容:" << text;
text = ui->lineEdit_2->text();
qDebug () << "第二个QLineEdit的内容:" << text;
}
3.Qt数据类型
Qt是一个跨平台的开发框架,所以必须保证各个平台下的数据类型长度一致。因为Qt为常见的基本类型数据类型定义了新的类型符号。

在Qt环境下,可以直接使用。

4.QTimer定时器类
QTimer类可以实现一个延时任务或者周期任务。
使用定时器,需要包含头文件#include<QTimer>。
QLcdNumber组件,使用此组件,显示出11:21:23

dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTimer> // 定时器
#include <QDateTime> // 时间和日期头文件
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
QTimer *timer; // 定时器对象
private slots:
void timeoutSlot();
};
#endif // DIALOG_H
dialog.cpp
cpp
```cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
timer = new QTimer(this);
// 提前刷新组件
timeoutSlot();
// 设置时间间隔(单位毫秒)
timer->setInterval(500);
// 默认为周期任务,如果想要设置为延时任务需要用到以下的函数
timer->setSingleShot(false); // 周期任务
connect(timer,SIGNAL(timeout()),
this,SLOT(timeoutSlot()));
timer->start();
}
Dialog::~Dialog()
{
delete timer;
delete ui;
}
void Dialog::timeoutSlot()
{
// 获取当前的系统时间
QDateTime dateTime = QDateTime::currentDateTime();
QString str = dateTime.toString("hh:mm:ss");
// 并且将时间显式到lcd组件中
ui->lcdNumber->display(str);
}
```
5.QMessageBox消息对话框
QMesageBox继承自QDialog,显示一个模态对话框,用于用户前台信息展示和询问用户问题并接受问题的答案。

cpp
// 参数1:parent参数
// 参数2:窗口标题
// 参数3:信息内容,窗口展示的信息
// 返回值:用户点击的按钮类型
StandardButton critical(QWidget * parent, const QString & title, const QString & text)
StandardButton information(QWidget * parent, const QString & title, const QString & text)
StandardButton question(QWidget * parent, const QString & title, const QString & text)
StandardButton warning(QWidget * parent, const QString & title, const QString & text)
[static]
dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QMessageBox>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void btnClickedSlotQ();
void btnClickedSlotI();
void btnClickedSlotW();
void btnClickedSlotC();
};
#endif // DIALOG_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButtonQ,SIGNAL(clicked()),
this,SLOT(btnClickedSlotQ()));
connect(ui->pushButtonI,SIGNAL(clicked()),
this,SLOT(btnClickedSlotI()));
connect(ui->pushButtonW,SIGNAL(clicked()),
this,SLOT(btnClickedSlotW()));
connect(ui->pushButtonC,SIGNAL(clicked()),
this,SLOT(btnClickedSlotC()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::btnClickedSlotQ()
{
QMessageBox::StandardButton stdb = QMessageBox::question(this,"question","是否需要关闭?");
if(stdb == QMessageBox::Yes)
{
close();
}
}
void Dialog::btnClickedSlotI()
{
QMessageBox::information(this,"information","已经加载完成");
}
void Dialog::btnClickedSlotW()
{
QMessageBox::warning(this,"warning","您的输入有误");
}
void Dialog::btnClickedSlotC()
{
QMessageBox::critical(this,"critical","程序异常,运行失败");
}
6.parent参数
parent参数表示子组件位于那个窗口中。
实际上parent参数还表示了Qt的内存回收机制,如果对象a作为对象b的构造函数时parent参数,表示对象a是对象b的父对象,这是一种内存的回收的依赖关系。即对象b跟随对象a销毁时一并销毁。此时无需控制对象b的销毁过程(手动编写delete)
如果堆内存对象创建时不传递parent参数,表示对对象的销毁需要手动编写delete。
绝大多数情况下,建议传递parent参数。
这样做也有缺点,缺点就是内存占用,如果a窗口还在,b对象窗口就不会被销毁。
7.堆栈窗口
通常作为独立窗口(组件),并且与QListWidget进行联动。

dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->listWidget,SIGNAL(currentRowChanged(int)),
ui->stackedWidget,SLOT(setCurrentIndex(int)));
}
Dialog::~Dialog()
{
delete ui;
}
8.新建自定义窗口类
1.在Qt Creator中选中项目名称,鼠标右键点击添加新文件。
2.在弹出的窗口中,按照下图所示进行操作。

3.在弹出的窗口中,选择界面模板后,点击下一步

4.在弹出的窗口中,输入类名(帕斯卡命名法/大驼峰),点击下一步

5.在项目管理界面直接点击完成,可以看到新的窗口类文件已经添加到项目中了。
ui如下

dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "mydialog.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void btnClickedSlot();
};
#endif // DIALOG_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),
this,SLOT(btnClickedSlot()));
}
void Dialog::btnClickedSlot()
{
MyDialog *mydlg = new MyDialog(this);
mydlg->show();
}
Dialog::~Dialog()
{
delete ui;
}
9.对象传值
9.1 父对象->子对象
此处指的是Qt的parent参数的依赖关系,并非继承关系。
【需求】:转动主窗口中的球, 子窗口中的球跟着转。
这种情况最佳的解决方案,就是使用C++的成员函数传参。

dialog.h
cpp
```cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QDebug>
#include "mydialog.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
MyDialog *mydlg;
private slots:
void btnClickedSlot();
void valueChangedSlot(int);
};
#endif // DIALOG_H
```
dialog.cpp
cpp
```cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),
this,SLOT(btnClickedSlot()));
}
void Dialog::btnClickedSlot()
{
mydlg = new MyDialog(this);
mydlg->show();
connect(ui->dial,SIGNAL(valueChanged(int)),
this,SLOT(valueChangedSlot(int)));
}
void Dialog::valueChangedSlot(int value)
{
// qDebug() << value;
mydlg->myDialogSetValue(value);
}
Dialog::~Dialog()
{
delete ui;
}
```
myDialog.h
cpp
```cpp
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
namespace Ui {
class MyDialog;
}
class MyDialog : public QDialog
{
Q_OBJECT
public:
explicit MyDialog(QWidget *parent = 0);
~MyDialog();
void myDialogSetValue(int);
private:
Ui::MyDialog *ui;
};
#endif // MYDIALOG_H
```
myDialog.cpp
cpp
```cpp
#include "mydialog.h"
#include "ui_mydialog.h"
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyDialog)
{
ui->setupUi(this);
}
MyDialog::~MyDialog()
{
delete ui;
}
void MyDialog::myDialogSetValue(int value)
{
ui->dial->setValue(value);
}
```
9.2 子对象→父对象
此处指的是Qt的parent参数的依赖关系,并非继承关系。
【需求】:转动子窗口中的球,主窗口中的球跟着转。
这种情况最佳的解决方案是信号槽传参,子对象发射带参数的信号函数,父对象使用参数的槽函数进行接收。
dialog.h
cpp
```cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QDebug>
#include "mydialog.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
MyDialog *mydlg;
private slots:
void btnClickedSlot();
void valueChangedSlot(int);
void valueSlot(int);
};
#endif // DIALOG_H
```
dialog.cpp
cpp
```cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),
this,SLOT(btnClickedSlot()));
}
void Dialog::btnClickedSlot()
{
mydlg = new MyDialog(this);
mydlg->show();
connect(ui->dial,SIGNAL(valueChanged(int)),
this,SLOT(valueChangedSlot(int)));
connect(mydlg,SIGNAL(valueSignal(int)),
this,SLOT(valueSlot(int)));
}
void Dialog::valueChangedSlot(int value)
{
// qDebug() << value;
mydlg->myDialogSetValue(value);
}
void Dialog::valueSlot(int value)
{
ui->dial->setValue(value);
}
Dialog::~Dialog()
{
delete ui;
}
```
myDialog.h
cpp
```cpp
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
namespace Ui {
class MyDialog;
}
class MyDialog : public QDialog
{
Q_OBJECT
public:
explicit MyDialog(QWidget *parent = 0);
~MyDialog();
void myDialogSetValue(int);
private:
Ui::MyDialog *ui;
private slots:
void myDialogValueChanedSlot(int);
signals:
void valueSignal(int);
};
#endif // MYDIALOG_H
```
myDialog.cpp
cpp
```cpp
#include "mydialog.h"
#include "ui_mydialog.h"
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyDialog)
{
ui->setupUi(this);
connect(ui->dial,SIGNAL(valueChanged(int)),
this,SLOT(myDialogValueChanedSlot(int)));
}
MyDialog::~MyDialog()
{
delete ui;
}
void MyDialog::myDialogSetValue(int value)
{
ui->dial->setValue(value);
}
void MyDialog::myDialogValueChanedSlot(int value)
{
// 发射带参数的自定义信号给父对象
emit valueSignal(value);
}
```
10.串口类
在Qt中,处理串口通信主要使用QSerialPort和QSerialPortInfo两个类。
QSerialPort:用于负责串口数据的读写。
QSerialPortInfo:负责获取系统的串口信息。
10.1 添加模块
需要在项目配置文件中添加对应的模块。
10.2 基础使用
1、串口初始化

dialog .h
cpp
```cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
QSerialPort *m_serial;
private slots:
void btnClickedConnectSlot();
void btnClickedSendSlot();
void serialReadyReadSlot();
};
#endif // DIALOG_H
```
dialog.cpp
cpp
```cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButtonIConnect,SIGNAL(clicked()),
this,SLOT(btnClickedConnectSlot()));
connect(ui->pushButtonSend,SIGNAL(clicked()),
this,SLOT(btnClickedSendSlot()));
// 串口对象创建
m_serial = new QSerialPort(this);
// 连接串口数据接收信号
connect(m_serial,SIGNAL(readyRead()),
this,SLOT(serialReadyReadSlot()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::btnClickedConnectSlot()
{
// 打开串口
// qDebug () << ui->comboBox->currentText();
m_serial->setPortName(ui->comboBox->currentText());
if(m_serial->open(QIODevice::ReadWrite))
{
qDebug() << "串口打开成功";
}
else
{
qDebug() << "串口打开失败";
}
}
void Dialog::btnClickedSendSlot()
{
// 接收用户输入的内容
QString str = ui->textEditSend->toPlainText();
// 将数据从字符串类型,转换为字符类型。并存储到字符数组
QByteArray data = str.toUtf8();
// 发送数据
m_serial->write(data);
}
void Dialog::serialReadyReadSlot()
{
// 读取数据
QByteArray data = m_serial->readAll();
// 显式到text中
ui->textEditRead->append(QString(data));
}
```
10.3 调试串口

将此软件下载到本地,并进行安装。
安装完成后,直接打开,可以看到如下界面:
选择连接的串口号,并点击添加
选择连接的串口号,并点击添加

添加完成后,可以看到如下界面
此时打开串口调试工具
运行自己的程序。
