QT应用开发学习(QT项目实战(仿写串口助手))

本文主要是记录自己是如何仿写串口助手并实现效果的(本文并没有串口测试,但是其他按键功能已经编写成功)



前言

我也是在b站学习的QT,之前学习了C++的基础知识,那么在QT中就能够很好的运用出来了,并且本人之前有学习过安卓,对GUI开发比较熟练,所以如果觉得自己基础不好的可以先看看C++的知识。本文直接粘贴全部代码并逐步讲解。


一、显示效果

在这里插入图片描述
ui是自己实现的,可以去查找一些类似的串口助手编写,其中运动模式、下载模式,隐藏面板,隐藏历史都还未编写逻辑,主要功能已经实现。

二、讲解代码

都说万事开头难,我们要写一个串口助手,我们就需要先写一个串口助手的界面,我们在把里面的逻辑实现即可。

1.UI布局

我们先讲一下所需要的控件:双击ui文件打开(拖动左边的控件到中间的编辑框):
在这里插入图片描述

Label标签:用来标志控件,主要是用来告诉用户这个是用来做什么的,通常用来写文字。
Horizontal Spacer:横向弹簧,用来保持两个控件的控距,可以在右下角修改弹簧大小来实现控件距离的控制。
Vertical Spacer:纵向弹簧,效果和横向弹簧一样,只是作用对象时方向是上下
PushButton:按钮,用来点击来触发其他事件
CheckBox:勾选框,用来判断用户是否点击,作用和按钮差不多,但是这个可直接看到结果
GroupBox:框柱大的集合,主要也是用来调整距离
ComboBox:下拉框,可设置不同的值供选择
LineEdit:行编辑,提供给用户来编辑一行数据
TextEdit:文本便捷,效果差不多和行编辑一样
PlainTextEdit:追加编辑,通常用于接收数据显示

在拖动完控件后,我们需要修改不同的控件名字,用来在代码中查找到,修改名字只需要单击一下要修改的控件,在右上角会有显示,按需修改即可(一般使用驼峰命名)。

主要用到就这些控件,接下需要学会的是灵活布局:
在这里插入图片描述
横向布局就是让控件按行排列,纵向布局就是让控件纵向排列,栅格布局就是让控件一个接一个排列,像教室里的上课座位一样。

一般每几个控件就能实现横向布局或纵向布局,全部固定好后在实现栅格布局

2.信号和槽

我们通常使用的控件具有不同的信号,我们可以在帮助文档中查找到,如QPushButton:
在这里插入图片描述
在这里插入图片描述
**我们可以看到哪些信号会触发槽函数,QT中特有的信号和槽机制,可以让控件在接收到相对应的信号是触发对应的槽函数。**当然我们也可以自己编写槽函数,自定义编写槽函数需要满足一下几个条件。

自定义编写槽函数

1.在你的类中声明自定义槽函数。槽函数是普通的成员函数,但在声明时需要使用slots关键字进行修饰。例如

class MyCustomClass : public QObject
{
    Q_OBJECT

public slots:
    void myCustomSlot();
};

2.在类的实现文件(.cpp)中定义槽函数。你可以像编写普通成员函数一样来实现自定义的槽函数。例如:

void MyCustomClass::myCustomSlot()
{
    // 这里编写槽函数的具体实现逻辑
    // ...
}

3.将槽函数和信号连接起来。槽函数可以通过调用Qt的信号与槽机制来响应特定的信号。一般情况下,你可以在构造函数或其他适当的地方,使用connect函数来建立槽函数和信号的连接。例如:

MyCustomClass::MyCustomClass()
{
    // 假设有一个QPushButton的点击信号连接到myCustomSlot()槽函数
    QPushButton* button = new QPushButton("Click me");
    connect(button, &QPushButton::clicked, this, &MyCustomClass::myCustomSlot);
}

connect

connect函数是Qt中用于建立信号与槽连接的函数。它允许你将一个信号连接到一个槽函数,以便在信号发出时执行槽函数的代码。

在Qt中,信号是一种特殊的成员函数,用于通知其他对象某个事件的发生。当满足特定条件时,一个对象可以发出一个信号。槽函数是普通的成员函数,用于响应信号的发出并进行相应的处理。

connect函数用于连接信号和槽函数,建立二者之间的关联。它的基本语法如下:

connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot);

其中,sender是发出信号的对象的指针(或者是静态成员函数所属的类),signal是发出的信号,receiver是接收信号的对象的指针,slot是接收信号时要执行的槽函数。

需要注意的是,信号和槽函数的参数类型必须匹配,或者是可以进行隐式转换的类型。此外,要确保信号和槽函数的声明都在QObject的子类中,并在类的声明中使用Q_OBJECT宏。

connect函数可以连接不同对象之间的信号和槽函数,可以连接同一个对象的不同信号和槽函数,也可以连接不同信号和不同槽函数。一个信号可以连接多个槽函数,多个信号也可以连接到同一个槽函数。

通过使用connect函数,你可以将对象间的通信通过信号和槽机制来实现。这种机制使得对象之间的耦合度降低,并提供了一种方便灵活的方式来处理事件。

自动实现槽函数

通常我们使用控件时,QT已经帮我们写好了槽函数,我们无需再自己编写connet,只需要在UI中右击控件,点击转到槽,然后确定自己选择的信号即可。这样我们就可以在槽函数中编写其中的逻辑了。

代码讲解:

QTSerial.pro

需要注意的是使用QT中的Serial函数需要在QT += core gui 加入serialport,这个可以在帮助文档中查看到
在这里插入图片描述

#-------------------------------------------------
#
# Project created by QtCreator 2023-07-16T13:41:42
#
#-------------------------------------------------

QT       += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QTSerial
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        qtserial.cpp

HEADERS += \
        qtserial.h

FORMS += \
        qtserial.ui

qtserial.h

#ifndef QTSERIAL_H
#define QTSERIAL_H

#include <QMainWindow>
#include <QSerialPort>
#include <QMessageBox>
#include <QComboBox>
#include <QCheckBox>
namespace Ui {
class QTSerial;
}

class QTSerial : public QMainWindow
{
    Q_OBJECT

public:
    explicit QTSerial(QWidget *parent = 0);
    ~QTSerial();

private slots://槽函数必须在这声明
    void on_OpenSerialBt_clicked();//打开串口按钮的槽函数声明
    void readyRead_slots();//准备读取的槽函数声明
    void on_sendBt_clicked();//发送按钮的槽函数声明
    void on_cleanSendEdit_clicked();//清空发送区的槽函数声明
    void on_CleanRec_clicked();//清空接收区的槽函数声明
    void on_HexPrint_stateChanged(int arg1);//进制转换的槽函数声明

private:
    Ui::QTSerial *ui;
    QSerialPort *serialport;//定义一个QSerialPort的指针变量,需要包含头文件<QSerialPort>,在QT中,包含类的头文件是无.h后缀的

};

#endif // QTSERIAL_H

qtserial.cpp

#include "qtserial.h"
#include "ui_qtserial.h"
#include <QDebug>
#include <QSerialPortInfo>
QTSerial::QTSerial(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::QTSerial)
{
    ui->setupUi(this);
    serialport = new QSerialPort(this);//new一个对象出来
    QStringList serialNamePort;//存储串口名称
    connect(serialport, SIGNAL(readyRead()), this, SLOT(readyRead_slots()));//当有数据进来的时候会触发这个槽函数

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//自动搜索串口信息
    {
        serialNamePort << info.portName();//将搜索到的串口信息给定义的类
    }

    ui->SerialBox->addItems(serialNamePort);
}

QTSerial::~QTSerial()
{
    delete serialport;
    delete ui;
}

void QTSerial::on_OpenSerialBt_clicked()
{
   if(serialport->open(QIODevice::ReadWrite) == true)
   {
       QMessageBox::information(this, "提示", "打开成功");
   }
   else
   {
       QMessageBox::information(this, "提示", "打开失败");
   }
    QString setBaudRate = ui->BoundBox->currentText();
    QString setDateBits = ui->DataBitBox->currentText();
    QString setParity = ui->ParityBox->currentText();
    serialport->setPortName(ui->SerialBox->currentText());//设置端口号
    switch (setBaudRate.toInt()) {
        case 4800:
            serialport->setBaudRate(4800);
            break;
        case 9600:
            serialport->setBaudRate(9600);
        case 115200:
            serialport->setBaudRate(115200);
            break;
        default:
            break;
    }
    switch (setDateBits.toInt()) {
        case 7:
            serialport->setDataBits(QSerialPort::Data7);
            break;
        case 8:
            serialport->setBaudRate(QSerialPort::Data8);
        default:
            break;
    }
    if(ui->StopBitBox->currentText() == "1"){
        serialport->setStopBits(QSerialPort::OneStop);
    }else if(ui->StopBitBox->currentText() == "1.5"){
            serialport->setStopBits(QSerialPort::OneAndHalfStop);
    }else if(ui->StopBitBox->currentText() == "2"){
            serialport->setStopBits(QSerialPort::TwoStop);
    }
    if(setParity == "None")
    {
        serialport->setParity(QSerialPort::NoParity);
    }

}
void QTSerial::readyRead_slots()//接收数据
{
    QString buf;
    buf = QString(serialport->readAll());
    ui->receTextEdit->appendPlainText(buf);
}
void QTSerial::on_sendBt_clicked()
{
    serialport->write(ui->sendlineEdit->text().toUtf8().data());
}

void QTSerial::on_cleanSendEdit_clicked()
{
    ui->sendlineEdit->clear();
}

void QTSerial::on_CleanRec_clicked()
{
    ui->receTextEdit->clear();
}

void QTSerial::on_HexPrint_stateChanged(int arg1)
{
    int sendLineEdit,decimalNumber1;
    QString decimalNumber;
    bool ok;
    QString hexString;
    switch (arg1) {
    case 0:
        decimalNumber = ui->sendlineEdit->text();
        decimalNumber1 = decimalNumber.toInt(&ok, 16);

        if (ok) {
            ui->sendlineEdit->setText(QString::number(decimalNumber1));
        } else {
            QMessageBox::warning(nullptr, "错误", "转换失败!");
        }
        break;
    case 2:
        sendLineEdit = ui->sendlineEdit->text().toInt();
        hexString = QString("%1").arg(sendLineEdit, 0, 16);
        ui->sendlineEdit->setText(hexString);
        break;
    default:
        break;
    }
}

总结

这就是仿写串口助手了,基本逻辑功能已经实现了,如果有什么错误请纠正。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,具有良好的可扩展性和易于使用的特点。而CSDN是一个国内知名的技术社区,提供了大量的编程教程和经验分享。 Qt项目实战CSDN可以是一个关于Qt开发的教程或者项目案例分享。在这个项目中,我会结合Qt的特点,通过撰写一系列的技术文章或者视频教程,详细介绍如何使用Qt进行应用程序的开发。 在这个项目中,我会从安装Qt开始,讲解Qt的基础知识,如界面设计、信号与槽机制、Qt对象模型等。然后,我会介绍Qt的高级特性,比如网络编程、数据库操作、多线程等。通过这些文章或者教程,读者可以系统地学习Qt的各个方面,从而快速掌握Qt的开发技巧。 同时,为了更好地帮助读者理解和学习Qt,我会结合实际的项目案例,展示如何使用Qt进行实际应用的开发。具体案例可以涵盖不同的领域,比如一个简单的音乐播放器、一个图像处理应用、一个聊天程序等。通过这些案例,读者可以更好地理解Qt的实际应用场景,并且通过参考案例代码,快速上手Qt的开发。 除了撰写技术文章或者制作视频教程,我还会积极参与到CSDN的技术社区中,回答读者的问题,与他们交流经验。这样可以进一步提升读者对于Qt开发的理解,并且根据读者的反馈,不断优化项目内容,使之更加符合读者的需求。 通过Qt项目实战CSDN,我希望能够帮助更多的开发者掌握Qt的开发技巧,实现自己的应用想法。同时,也希望能够通过与读者的交流,不断提升自己的技术水平,共同促进技术的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值