第81讲 串口调试助手实现自动发送
为这个名叫“定时发送”的QCheckBox编写槽函数。
想要做出定时发送的效果,必须引入QT框架下的毫秒级定时器QTimer,查阅手册了解详情。
在widget.h内添加新的私有成员变量:
QTimer *timer;
在widget类的构造函数内部进行变量初始化:
ui->setupUi(this);
this->setLayout(ui->gridLayoutGlobal);
writeCntGobal=0;
readCntGobal=0;
serialStatus=false;
serialPort = new QSerialPort(this);
timer=new QTimer(this);
关联信号与槽函数,信号是timeout超时函数,槽函数是发送文本函数:
connect(timer,&QTimer::timeout,[=](){
on_btnSendContext_clicked();
});
先测试一下信号与槽是否成功关联,checkBox槽函数的逻辑是勾选后定时器开起,超时后执行槽函数然后自动重装载,如果没有勾选就关闭定时器:
void Widget::on_checkBoxSendInTime_clicked(bool checked)
{
if(checked)
{
timer->start(ui->lineEditTimeeach->text().toInt());
}else{
timer->stop();
}
}
测试结果如下,1S发两个,程序正常跑起来了。
接下来,我们会在串口关闭状态下屏蔽“定时发送”按键与“发送”按键;
打开串口定时发送时,屏蔽发送频率输入框与文本输入框。
setEnabled方法可以屏蔽上述的所有控件,进入一种“不可选中”的状态。其次,对于可以勾选的Check Box,setCheckState方法可以取消勾选状态对控件进行重置。
综上所述:
#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();
}
}