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讲 如何自我验证新控件

相关推荐
敬往事一杯酒哈6 小时前
海康 AGV 导航读码器学习
学习
qq_284274058 小时前
机械原理笔记:平面机构自由度计算(复合铰链、局部自由度、虚约束)与四杆机构入门(含考点)
笔记·学习·平面·自动化·制造
qq_284274059 小时前
数控铣床与加工中心笔记:铣刀与刀柄系统、G54试切对刀、镜像加工指令、孔加工工艺(钻扩铰镗)与固定循环G73/G83/G81/G76/G87/G84
笔记·学习·自动化·制造
Titan202410 小时前
MySQL访问个人学习笔记
笔记·学习·mysql
小雪崩11 小时前
嵌入式学习 day64:字符设备驱动
学习
深圳老胡11 小时前
STM32CubeMX 生成 CMake 工程,用 VSCode 编译与调试的完整流程
笔记·stm32·单片机·代码规范
个 人 练 习 生11 小时前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
坤坤子吖11 小时前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
乐橙开放平台12 小时前
智慧连锁客流检测和离岗检测怎么对接
大数据·人工智能·笔记·物联网·自动化·音视频·智能家居
零基础12312 小时前
FinalShell 使用教程:从安装到高效运维
运维·经验分享·笔记·finalshell