P4 QT项目----串口助手(4.2)
4.2.1串口助手打开串口
按键进行信号与槽的连接实现
//1.选择串口端号
//2.配置波特率
//3.配置数据位
//4.配置校验位
//5.配置停止位
//6.流控
//7.打开串口
4.2.2串口助手进行自收自发功能
1.发送数据
//1.数据类型转换 QString 转为 const char*
//2.数据发送大小serialPort->write(sendData);
//3.判断数据是否发送成功
2.接收数据
//1.接收数据类型QString recMessage = serialPort->readAll();
//2.判断是否开始接收
//3.获取字符串大小receiveCntTotal += recMessage.size();
//4.将数据输出到面板上
4.2.3串口助手发送状态优化
//1.未打开串口时,串口的端口号、波特率等信息可以选择,发送按键,定时发送按键机定时时间不能点击,需要打开串口后才能使用
//2.打开串口后,串口的端口号、波特率等信息不可以选择,发送按键,定时发送按键机定时时间能点击,需要关闭串口后才能使用
4.2.4串口助手实现定时自动发送功能
//1.建立一个定时器connect(timer,&QTimer::timeout,[=](){on_pushButton_Send_clicked();});
//2.判断checked的状态进行自动发送
//3.打开定时器开始发送
//4.发送完毕时需要把定时器关闭
4.2.4串口助手保存清空接收数据
1.清空
//1.建立一个信号与槽连接函数
//2.将文本清空或写入空字符
2.保存
//1.建立一个信号与槽连接函数
//2.将文本建立一个QFileDialog和QTextStream来保存文件
4.2.4串口助手获取系统时间
//1.建立一个信号与槽连接函数QDateTime
//2.将时间显示在右下角
整体代码实现:
#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QCheckBox>
#include <QFileDialog>
#include <QDateTime>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//跟随界面放大缩小
this->setLayout(ui->gridLayout_Global);
//变量初始化
writeCntTotal = 0;
receiveCntTotal = 0;
serialStatus = false;
ui->pushButton_Send->setEnabled(false); /* 串口未打开,不能点击发送 */
ui->checkBox_SendInTime->setEnabled(false); /* 串口未打开,不能点击定时发送 */
ui->lineEdit_TimeEach->setEnabled(false); /* 串口未打开,不能编辑定时时间 */
ui->checkBox_SendNewLine->setEnabled(false);/* 串口未打开,不能点击发送新行 */
ui->checkBox_HexSend->setEnabled(false); /* 串口未打开,不能点击发送HEX进制 */
ui->checkBox_InputFormat->setEnabled(false);/* 串口未打开,不能点击发送格式输入 */
serialPort = new QSerialPort(this); /*定义一个新空间给serialPort*/
timer = new QTimer(this); /*定义一个新空间给timer*/
getSysTimer = new QTimer(this); /*定义一个新空间给getSysTimer*/
connect(getSysTimer,SIGNAL(timeout()),this,SLOT(time_Reflash()));
getSysTimer->start(100); /* 开启定时器getSysTimer */
//设置波特率115200和数据位8位
ui->comboBox_BoardRate->setCurrentIndex(6);
ui->comboBox_DataBit->setCurrentIndex(3);
//数据接收界面需要一个信号与槽的连接
connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_serialData_readyToRead); /*函数指针形式*/
connect(timer,&QTimer::timeout,[=](){
on_pushButton_Send_clicked(); });
//将电脑端口的串口号显示在串口调试助手上
QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
for(QSerialPortInfo serialInfo : serialList) /* for循环遍历serialList */
{
qDebug() << serialInfo.portName(); /* 输出串口号 */
ui->comboBox_Serial->addItem(serialInfo.portName()); /* 打印串口号在调试助手combox上 */
}
}
Widget::~Widget()
{
delete ui;
}
/* 打开 or 关闭串口 */
void Widget::on_pushButton_OpenOrCloseSerial_clicked()
{
if(!serialStatus){ /* 方式1---状态位
方式2---该按键在ui界面的属性QAbstructButtons-checkable打开,
在重新生成槽函数(bool) */
//1.选择串口端号
serialPort->setPortName(ui->comboBox_Serial->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_BoardRate->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_DataBit->currentText().toUInt()));
//4.配置校验位
switch (ui->comboBox_CheckBit->currentIndex()) {
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::MarkParity);
break;
case 3:
serialPort->setParity(QSerialPort::OddParity);
break;
case 4:
serialPort->setParity(QSerialPort::SpaceParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_StopBit->currentText().toUInt()));
//6.流控
if(ui->comboBox_FluidCon->currentText() == "None")
serialPort->setFlowControl(QSerialPort::NoFlowControl);
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)){
qDebug() << "serial open success.";
ui->comboBox_Serial->setEnabled(false); /* 串口已经打开,不能选择串口端号 */
ui->comboBox_DataBit->setEnabled(false); /* 串口已经打开,不能选择数据位 */
ui->comboBox_StopBit->setEnabled(false); /* 串口已经打开,不能选择停止位 */
ui->comboBox_CheckBit->setEnabled(false); /* 串口已经打开,不能选择校验位 */
ui->comboBox_FluidCon->setEnabled(false); /* 串口已经打开,不能选择流控 */
ui->comboBox_BoardRate->setEnabled(false); /* 串口已经打开,不能选择波特率 */
ui->pushButton_OpenOrCloseSerial->setText("关闭串口");
ui->pushButton_Send->setEnabled(true); /* 串口已经打开,点击发送 */
ui->checkBox_SendInTime->setEnabled(true); /* 串口已经打开,点击定时发送 */
ui->lineEdit_TimeEach->setEnabled(true); /* 串口已经打开,编辑定时时间 */
ui->checkBox_SendNewLine->setEnabled(true); /* 串口已经打开,点击发送新行 */
ui->checkBox_HexSend->setEnabled(true); /* 串口已经打开,点击发送HEX进制 */
ui->checkBox_InputFormat->setEnabled(true); /* 串口已经打开,点击发送格式输入 */
serialStatus = true;
}else{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用或者已拔出!");
msgBox.exec();
}
}else{
serialPort->close();
qDebug() << "serial close success.";
ui->comboBox_Serial->setEnabled(true); /* 串口已经关闭,能选择串口端号 */
ui->comboBox_DataBit->setEnabled(true); /* 串口已经关闭,能选择数据位 */
ui->comboBox_StopBit->setEnabled(true); /* 串口已经关闭,能选择停止位 */
ui->comboBox_CheckBit->setEnabled(true); /* 串口已经关闭,能选择校验位 */
ui->comboBox_FluidCon->setEnabled(true); /* 串口已经关闭,能选择流控 */
ui->comboBox_BoardRate->setEnabled(true); /* 串口已经关闭,能选择波特率 */
ui->pushButton_OpenOrCloseSerial->setText("打开串口");
ui->pushButton_Send->setEnabled(false); /* 串口未打开,不能点击发送 */
ui->checkBox_SendInTime->setEnabled(false); /* 串口未打开,不能点击定时发送 */
ui->lineEdit_TimeEach->setEnabled(false); /* 串口未打开,不能编辑定时时间 */
ui->checkBox_SendNewLine->setEnabled(false);/* 串口未打开,不能点击发送新行 */
ui->checkBox_HexSend->setEnabled(false); /* 串口未打开,不能点击发送HEX进制 */
ui->checkBox_InputFormat->setEnabled(false);/* 串口未打开,不能点击发送格式输入 */
serialStatus = false;
ui->checkBox_SendInTime->setCheckState(Qt::Unchecked); /* 关闭串口,将定时发送状态改为Unchecked,取消定时发送 */
timer->stop();
}
}
/* 发送按键 */
void Widget::on_pushButton_Send_clicked()
{
int writeCnt = 0;
const char *sendData = ui->lineEdit_SendData->text().toLocal8Bit().constData(); /* 数据类型,Qstring 转 const char * */
writeCnt = serialPort->write(sendData); /* 记录发送数据大小 */
if(writeCnt == -1){
ui->label_Refresh->setText("Send Error!"); /* Returns the number of bytes that were actually written, or -1 if an error occurred. */
}else{
writeCntTotal += writeCnt;
qDebug() << "Send OK!" << sendData;
ui->label_Refresh->setText("Send Ok!"); /* 数据发送成功 */
//ui->label_Sent->setNum(writeCntTotal); /* 数据发送多少 */
ui->label_Sent->setText("Sent:" + QString::number(writeCntTotal)); /* 在底部显示发送数据的大小 */
//比较前后两次发送的数据是否一致,一致在历史接收界面只显示一次
if(strcmp(sendData,sendBack.toStdString().c_str()) != 0){
ui->textEdit_Record->append(sendData); /* 发送到历史记录界面 */
sendBack = QString::fromUtf8(sendData); /* 缓存sendData数据 */
}
}
}
/* 接收数据进行信号与槽的绑定 */
void Widget::on_serialData_readyToRead()
{
QString recMessage = serialPort->readAll(); /* 接收发送的数据 */
if(recMessage != NULL){
qDebug() << "recMessage:" << recMessage;
ui->textEdit_Receive->append(recMessage); /* 将接收到的数据发送到接收界面上 */
receiveCntTotal += recMessage.size(); /* 获取字符串大小 */
//ui->label_Receive->setNum(receiveCntTotal); /* 数据接收多少 */
ui->label_Receive->setText("Received:" + QString::number(receiveCntTotal));
}
}
/* 定时发送 */
void Widget::on_checkBox_SendInTime_clicked(bool checked)
{
//qDebug() << "checkButton Intime!" << checked;
if(checked){
ui->lineEdit_TimeEach->setEnabled(false); /* 定时发送打开,不能编辑定时时间 */
ui->pushButton_Send->setEnabled(false); /* 定时发送打开,不能点击发送 */
ui->lineEdit_SendData->setEnabled(false); /* 定时发送打开,不能编辑文本 */
timer->start(ui->lineEdit_TimeEach->text().toInt());
}else{
ui->lineEdit_TimeEach->setEnabled(true); /* 定时发送关闭,能编辑定时时间 */
ui->pushButton_Send->setEnabled(true); /* 定时发送关闭,点击发送 */
timer->stop();
}
}
/* 清空接收 */
void Widget::on_pushButton_ClearRec_clicked()
{
ui->textEdit_Receive->setText("");
}
/* 保存接收 */
void Widget::on_pushButton_SaveRec_clicked()
{
//保存文件的类型,位置
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "D:Embedded_learning/03.QT_Codeinlesson/P4_Serial-Port/Serial.txt",
tr("Text (*.txt)"));
QFile file(fileName); /* 打开文件 */
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) /* 如果文件未打开,跳出函数 */
return;
QTextStream out(&file); /* 输入文件内容 */
out << ui->textEdit_Receive->toPlainText(); /* 将接收区的内容保存到该文件.txt */
file.close();
}
/* 定时器getSysTimer的信号与槽函数 */
void Widget::time_Reflash()
{
getSysTime(); /* 调用获取系统时间函数 */
ui->label_DataTime->setText(Mytime); /* 将时间显示在界面上 */
}
/* 获取系统时间 */
void Widget::getSysTime()
{
//It combines features of the QDate and QTime classes.
QDateTime currentTime = QDateTime::currentDateTime(); /* 获取当前的日期 */
//获取年月日
QDate date = currentTime.date();
int year = date.year();
int month = date.month();
int day = date.day();
//获取时分秒
QTime time = currentTime.time();
int hour = time.hour();
int minute = time.minute();
int second = time.second();
//抢占符号
Mytime = QString("%1-%2-%3 %4:%5:%6")
.arg(year,2,10,QChar('0'))
.arg(month,2,10,QChar('0'))
.arg(day,2,10,QChar('0'))
.arg(hour,2,10,QChar('0'))
.arg(minute,2,10,QChar('0'))
.arg(second,2,10,QChar('0'));
/*
QString arg(int a, int fieldWidth = 0, int base = 10, QChar fillChar =QLatin1Char(' ')) const
*/
//qDebug() << Mytime;
}