Qt速通2

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 调试串口

将此软件下载到本地,并进行安装。

安装完成后,直接打开,可以看到如下界面:

选择连接的串口号,并点击添加

选择连接的串口号,并点击添加

添加完成后,可以看到如下界面

此时打开串口调试工具

运行自己的程序。

虚拟串口使用完毕后,建议删除,否则虚拟串口会一直存在并开启。

相关推荐
“AI国潮设计-小江”2 小时前
【Python/SDXL实战】潮汕国潮IP视觉落地:普宁英歌舞猫IP & 创意甜品设计(附ComfyUI工作流与商业授权说明)
开发语言·人工智能·python·prompt·aigc
529宝宝起名网2 小时前
用 Python 分析汉字字源与起名用字的关联规律:从六书结构到文化寓意的起名偏好洞察
开发语言·python
linx2953 小时前
单元九 · 零基础路线图-第 7–9 周·类与 RAII
c语言·开发语言·数据结构·c++·嵌入式硬件·算法
心态还需努力呀3 小时前
把 Flameshot 编译进鸿蒙 PC:一次 Qt C++ 截图工具的源码级移植实战
c++·qt·harmonyos
白色的北极熊4 小时前
c语言 输出菱形字符串
c语言·开发语言
学习智者4 小时前
《玄》IDE v3.6.3重磅发布:全功能修复与性能飞跃
开发语言·c++·ide·算法·中文语言 玄
奔跑吧树袋熊4 小时前
多租户隔离该做到哪一层:从连接池到 ORM 的取舍
开发语言·数据库·oracle·系统架构
大江东去浪淘尽千古风流人物4 小时前
【LoMa】局部特征匹配重访:从LoMa-B到旋转不变LoMa-R的架构与工程实践
开发语言·深度学习·计算机视觉·r语言·视觉定位·sfm·局部特征匹配
菜鸟~noob2334 小时前
【电子战】测向精度极限——克拉美-罗下限(CRLB)与误差分析【含matlab代码】
开发语言·matlab