#include "maindialog.h"
#include "ui_maindialog.h"
#include <QDebug>//调试输出,可以直接输出Qt对象
#include <QMessageBox>//弹出对话框用的,用于提示用户
#include <QSerialPortInfo>//获取系统串口信息
#include <QSerialPort>//使用Qt自带的串口类
ConfigData configData;//默认的串口配置参数
MainDialog::MainDialog(QWidget *parent) ://本程序的主界面的构造函数
QDialog(parent),//初始化列表,先初始化父类对象
ui(new Ui::MainDialog)//初始化列表,再初始化UI类对象
{
ui->setupUi(this);//创建及初始化界面各控件
m_serial = new QSerialPort(this);//创建一个串口对象,作为本对话框的一个子类。
connect(m_serial, &QSerialPort::readyRead, this, &MainDialog::slotSerialRecv);//关联接收事件的槽函数
//采用槽函数,可方便的接收串口数据。当出现串口硬件上收到数据时,会自动产生readyRead信号,并触发关联的槽函数
//或者不采用信号槽机制,而采用查询方式,定时调用读取函数来读取串口数据,并解析处理。需增加定时器或者子线程。
showUIConfigData(configData);//将默认的串口配置信息显示在页面中
connect(this, &MainDialog::echoSignal,this, &MainDialog::serialSend,Qt::QueuedConnection);//连接自定义的接收后通知处理的信号和槽,采用队列缓存机制//不可多次连接
}
MainDialog::~MainDialog()//本程序主界面的析构函数
{
delete m_serial;//析构new的串口对象。
delete ui;//析构顺序与构造相反,先声明的变量后析构,后声明的变量先析构 //Author:28mark-Q28121
}
/**
函数功能:获取本机所有串口
输入输出:无
返回值:void
说明:会读取本机硬件串口号
**/
void MainDialog::getAvailableSerialPort()
{
ui->cbSerialPort->clear();//清空组合框里的现有的串口号选项,以添加最新值
ui->cbSerialPort->insertItem(0,configData.name);//在串口号组合框中,插入第一个默认的项
ui->cbSerialPort->setCurrentIndex(0);//将第0项设为当前默认项
//简化版for语法:前面是一个循环变量,代表后面是一个列表,每次循环从后面取一个值更新过去
for (auto portInfo: QSerialPortInfo::availablePorts())//获取本机所有串口名称
{
ui->cbSerialPort->addItem(portInfo.portName());//将串口名添加到组合框中,采用addItem()函数添加一个字符串选项
}
}
/**
函数功能:查找本机支持的串口端口号并根据配置文件,重新显示UI界面
输入输出:ConfigData& configData
返回值:void
说明:将配置文件的值放到第一个上,以便用户选择
**/
void MainDialog::showUIConfigData(ConfigData& configData)
{
getAvailableSerialPort();//获取硬件串口信息
ui->cbBaudRate->clear();//清空现有的波特率选项
ui->cbBaudRate->insertItem(0,QString::number(configData.baudRate));//在波特率组合框中,插入第一个默认的项
ui->cbBaudRate->setCurrentIndex(0);//设置当前项
ui->cbBaudRate->addItem("1200");//添加其它的波特率
ui->cbBaudRate->addItem("2400");//添加其它的波特率
ui->cbBaudRate->addItem("4800");//添加其它的波特率
ui->cbBaudRate->addItem("9600");//添加其它的波特率
ui->cbBaudRate->addItem("38400");//
ui->cbBaudRate->addItem("57600");//
ui->cbBaudRate->addItem("115200");//
}
/**
函数功能:用户新安装串口设备时调用
输入输出:
返回值:void
说明:可防止用户先打开本软件,后插上USB转串口工具后,无法及时刷新出串口信息的情况
**/
void MainDialog::on_btnFillAvailablePorts_clicked()
{
getAvailableSerialPort();//需要刷新本机端口号
}
/**
函数功能:将帧转换成字符串
输入输出:unsigned char*buf 帧缓存数据, unsigned int bufLen 帧长度
返回值:QString 转换后的字符串
说明:方便打印调试
**/
QString MainDialog::toString(char*buf, unsigned int bufLen)
{
QString str("");
str += QString("Len %1,").arg(bufLen);//报文的长度
unsigned int i = 0;
for ( ; i < bufLen; ++i)//打印报文体
str += QString(" %1").arg((unsigned char)buf[i], 2, 16, QLatin1Char('0'));//按照16进制输出,不足两位时前面补零
return str;
}
/**
函数功能:获取页面最新填写的参数配置
输入输出:ConfigData &configData
返回值:void
说明:在点击打开串口时,需要先调用该函数,获取最新配置
**/
void MainDialog::freshConfigData(ConfigData &configData)
{
//使用Qt的控件QComboBox类带的currentText()函数,可以获取当前被选中选项的文本。
configData.name = ui->cbSerialPort->currentText().trimmed();//获取端口号
configData.baudRate = ui->cbBaudRate->currentText().trimmed().toInt();//获取波特率
}
/**
函数功能:点击“打开串口”的槽函数
输入输出:
返回值:
说明:先获取界面参数,再清空残留数据,判断并避免二次打开,设置串口参数,打开串口,检测是否打开成功
**/
void MainDialog::on_btnOpen_clicked()
{
QString info;//存放提示信息
freshConfigData(configData);//打开端口前需要获取当前配置参数
recvBuf.clear();//清除接收缓存
sendCount = 0;//发送帧计数
recvCount = 0;//接收帧计数
if (m_serial->isOpen())//是否已打开,避免二次关闭
m_serial->close();//若已打开,则先关闭再打开,以更新串口参数
m_serial->setPortName(configData.name);//设定端口号,采用保存的configData结构体数据
m_serial->setBaudRate(configData.baudRate);//设定波特率
//serial.setDataBits(QSerialPort::Data8);//设置数据位,其它参数一般用不到,此处略
//serial.setParity(QSerialPort::NoParity);//设置校验位
//serial.setStopBits(QSerialPort::OneStop);//设定停止位 //Author:28mark-Q28121
//serial.setFlowControl(QSerialPort::NoFlowControl);//关闭流控
if (!m_serial->open(QIODevice::ReadWrite))//以读写方式打开串口,打开成功则返回true
{
info = QString("Can't open %1, error code %2").arg(m_serial->portName()).arg(m_serial->error());//将错误信息通过调试窗口打印出来,以便开发过程中调试用。
qDebug()<<info;
ui->lblPrompt->setText(info);
QMessageBox(QMessageBox::Critical, "ERROR",info);//给用户提示打开的错误信息
return;//返回本函数,不再继续
}else
{
info = QString("serial %1 is opened true").arg(m_serial->portName());//打印调试信息
qDebug()<<info;
ui->lblPrompt->setText(info);
m_serial->flush();//刷掉上次的数据,防止干扰本次通信
}
//调整界面的按钮状态
ui->btnSend->setEnabled(true);//允许"发送"
}
/**
函数功能:点击“关闭串口”的槽函数
输入输出:
返回值:
说明:先判断是否已打开,以避免二次关闭,同时更新界面上的按钮状态
**/
void MainDialog::on_btnClose_clicked()
{
QString info;
info = QString("serial %1 is close").arg(m_serial->portName());//打印调试信息
if (m_serial->isOpen())//是否已打开,避免二次关闭
m_serial->close();//二次关闭试过,也没问题
//调整界面的按钮状态
ui->btnSend->setEnabled(false);//关闭发送
info += " true.";
qDebug()<<info;
ui->lblPrompt->setText(info);
}
/**
函数功能:点击“发送”的槽函数
输入输出:
返回值:
说明:获取发送窗口里的数据,将字符串转换为QByteArray再发送
**/
void MainDialog::on_btnSend_clicked()
{
QString str;
str = ui->lineSend->text();//获取编�
评论0