Qt学习笔记第81到90讲

第81讲 串口调试助手实现自动发送

为这个名叫"定时发送"的QCheckBox编写槽函数。

想要做出定时发送的效果,必须引入QT框架下的毫秒级定时器QTimer,查阅手册了解详情。

在widget.h内添加新的私有成员变量:

cpp 复制代码
    QTimer *timer;

在widget类的构造函数内部进行变量初始化:

cpp 复制代码
    ui->setupUi(this);
    this->setLayout(ui->gridLayoutGlobal);
    writeCntGobal=0;
    readCntGobal=0;
    serialStatus=false;
    serialPort = new QSerialPort(this);
    timer=new QTimer(this);

关联信号与槽函数,信号是timeout超时函数,槽函数是发送文本函数:

cpp 复制代码
    connect(timer,&QTimer::timeout,[=](){
        on_btnSendContext_clicked();
    });

先测试一下信号与槽是否成功关联,checkBox槽函数的逻辑是勾选后定时器开起,超时后执行槽函数然后自动重装载,如果没有勾选就关闭定时器:

cpp 复制代码
void Widget::on_checkBoxSendInTime_clicked(bool checked)
{
  if(checked)
  {
     timer->start(ui->lineEditTimeeach->text().toInt());
  }else{
     timer->stop();

  }
}

测试结果如下,1S发两个,程序正常跑起来了。

接下来,我们会在串口关闭状态下屏蔽"定时发送"按键与"发送"按键;

打开串口定时发送时,屏蔽发送频率输入框与文本输入框。

setEnabled方法 可以屏蔽上述的所有控件,进入一种"不可选中"的状态。其次,对于可以勾选的Check Box,setCheckState方法可以取消勾选状态对控件进行重置。

综上所述:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

#include <QMessageBox>
#include <QSerialPort>

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setLayout(ui->gridLayoutGlobal);
    writeCntGobal=0;
    readCntGobal=0;
    serialStatus=false;
    serialPort = new QSerialPort(this);
    timer=new QTimer(this);

    connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_serialData_readytoRead);
    connect(timer,&QTimer::timeout,[=](){
        on_btnSendContext_clicked();
    });

    ui->comboBox_baudRate->setCurrentIndex(6);
    ui->comboBox_dataBit->setCurrentIndex(3);

    QList <QSerialPortInfo> serialList=QSerialPortInfo::availablePorts();
    for(QSerialPortInfo serialInfo:serialList)
    {
        //qDebug()<<serialInfo.portName();
        ui->comboBox_serialNum->addItem(serialInfo.portName());
    }

    ui->btnSendContext->setEnabled(false);
    ui->checkBoxSendInTime->setEnabled(false);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_btnCloseOrOpenSerial_clicked()
{
    if(serialStatus==false)
    {

        //1.选择端口号
        serialPort->setPortName(ui->comboBox_serialNum->currentText());
        //2.配置波特率
        serialPort->setBaudRate(ui->comboBox_baudRate->currentText().toInt());
        //3.配置数据位
        serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_dataBit->currentText().toUInt()));
        //4.配置校验位
        /*MARK DOWN :
    enum Parity {
        NoParity = 0,
        EvenParity = 2,
        OddParity = 3,
        SpaceParity = 4,
        MarkParity = 5,
        UnknownParity = -1
    };
    Q_ENUM(Parity)
  */
        switch(ui->comboBox_checkBit->currentIndex())
        {
        case 0:
            serialPort->setParity(QSerialPort::NoParity);
            break;

        case 1:
            serialPort->setParity(QSerialPort::EvenParity);
            break;

        case 2:
            serialPort->setParity(QSerialPort::OddParity);
            break;

        case 3:
            serialPort->setParity(QSerialPort::SpaceParity);
            break;

        case 4:
            serialPort->setParity(QSerialPort::MarkParity);
            break;


        default:
            serialPort->setParity(QSerialPort::UnknownParity);
            break;
        }
        //5.配置停止位
        serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopBit->currentText().toInt()));
        //6.流控
        if(ui->comboBox_fileCon->currentText()=="None")
            serialPort->setFlowControl(QSerialPort::NoFlowControl);
        //7.打开串口
        if(serialPort->open(QIODevice::ReadWrite))
        {
            qDebug()<<"serial open";

            serialStatus=true;
            ui->btnSendContext->setEnabled(true);

            ui->btnCloseOrOpenSerial->setText("关闭串口 ");
            ui->comboBox_dataBit->setEnabled(false);
            ui->comboBox_fileCon->setEnabled(false);
            ui->comboBox_stopBit->setEnabled(false);
            ui->comboBox_baudRate->setEnabled(false);
            ui->comboBox_checkBit->setEnabled(false);
            ui->comboBox_serialNum->setEnabled(false);

            ui->checkBoxSendInTime->setEnabled(true);

        }else{
            QMessageBox msgBox;
            msgBox.setWindowTitle("错误");
            msgBox.setText("此串口已被占用或拔出!");
            msgBox.exec();
        }
    }else{
        serialStatus=false;
        ui->btnSendContext->setEnabled(false);

        serialPort->close();
        ui->btnCloseOrOpenSerial->setText("打开串口 ");
        ui->comboBox_dataBit->setEnabled(true);
        ui->comboBox_fileCon->setEnabled(true);
        ui->comboBox_stopBit->setEnabled(true);
        ui->comboBox_baudRate->setEnabled(true);
        ui->comboBox_checkBit->setEnabled(true);
        ui->comboBox_serialNum->setEnabled(true);

        ui->checkBoxSendInTime->setEnabled(false);
        ui->checkBoxSendInTime->setCheckState(Qt::Unchecked);
        timer->stop();
        ui->lineEditTimeeach->setEnabled(true);
        ui->lineEditSendContext->setEnabled(true);
    }
}

void Widget::on_btnSendContext_clicked()
{
    int writeCnt=0;

    const char* sendData=ui->lineEditSendContext->text().toStdString().c_str();
    writeCnt=serialPort->write(sendData);

    if(writeCnt==-1){
        ui->labelSendStatus->setText("Send Error!");
    }else{
        writeCntGobal+=writeCnt;
        qDebug()<<"Send Ok! "<<sendData;

        ui->labelSendStatus->setText("Send Ok!");
        ui->labelSendcnt->setNum(writeCntGobal);

        if(strcmp(sendData,sendBack.toStdString().c_str())!=0)
        {
            ui->textEditRecord->append(sendData);
            sendBack=QString(sendData);
        }
    }
}

void Widget::on_serialData_readytoRead()
{
    QString revMessage=serialPort->readAll();

    if(revMessage!=NULL){
        qDebug()<<"getMessage:"<<revMessage;
        ui->textEditRev->append(revMessage);
        readCntGobal+=revMessage.size();
        ui->labelRevcnt->setNum(readCntGobal);
    }else{


    }
}

void Widget::on_checkBoxSendInTime_clicked(bool checked)
{
  if(checked)
  {
     ui->lineEditTimeeach->setEnabled(false);
     ui->lineEditSendContext->setEnabled(false);
     timer->start(ui->lineEditTimeeach->text().toInt());
  }else{
     ui->lineEditTimeeach->setEnabled(true);
     ui->lineEditSendContext->setEnabled(true);
     timer->stop();

  }
}

第82讲 如何自我验证新控件

相关推荐
wdfk_prog21 小时前
[Linux]学习笔记系列 -- lib/dump_stack.c 栈回溯打印(Stack Trace Dumping) 内核调试与错误诊断的基石
linux·运维·服务器·c语言·笔记·学习
i.ajls21 小时前
无监督学习,推荐系统以及强化学习笔记
笔记·学习·机器学习
dragoooon3421 小时前
[优选算法专题二滑动窗口——串联所有单词的子串]
数据结构·c++·学习·算法·leetcode·学习方法
向阳花开_miemie21 小时前
Android音频学习(十七)——音频数据流转
学习·音视频
聆风吟º21 小时前
【Spring Boot 报错已解决】Web server failed to start. Port 8080 was already in use.
spring boot·笔记·技术干货
Suckerbin21 小时前
LAMPSecurity: CTF6靶场渗透
笔记·安全·web安全·网络安全
Brookty21 小时前
【算法】双指针(二)复写零
学习·算法
特种加菲猫21 小时前
并发编程的守护者:信号量与日志策略模式解析
linux·笔记·策略模式
赶飞机偏偏下雨1 天前
【Java笔记】单例模式
java·笔记·单例模式
滴滴滴嘟嘟嘟.1 天前
Qt UDP通信学习
qt·学习·udp