临沂购买模板建站,wordpress 安装变下载,做一个推广网站大概多少钱,网站搭建功能需求前言
1.一直都想要做一个Qt上位机#xff0c;趁着这个周末有时间#xff0c;动手写一下
2.comboBox没有点击的信号#xff0c;所以做了一个触发的功能
3.Qt的数据类型很奇怪#xff0c;转来转去的我也搞得很迷糊
4.给自己挖个坑#xff0c;下一期做一个查看波形的上位…前言
1.一直都想要做一个Qt上位机趁着这个周末有时间动手写一下
2.comboBox没有点击的信号所以做了一个触发的功能
3.Qt的数据类型很奇怪转来转去的我也搞得很迷糊
4.给自己挖个坑下一期做一个查看波形的上位机
有纰漏请指出转载请说明。
学习交流请发邮件 1280253714qq.com 串口功能
波特率设置
串口开关
串口异常检测
字符串/HEX收发
定时发送
接收数据分隔
协议组包
协议拆包 源代码
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include QWidget
#include QtSerialPort/QSerialPort // 提供访问串口的功能
#include QtSerialPort/QSerialPortInfo // 提供系统中存在的串口信息
#include QTime
#include QtCharts
#include QTimerQT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECT//用于表格设置enum FieldColNum {colTime,colCmd1,colCmd2,colData,};enum CellType {ctTime,ctCmd1,ctCmd2,ctData,};
public:int tableRowCnt 0;
public:Widget(QWidget *parent nullptr);~Widget();void serialPortInit(); //串口初始化void windowInit(); //显示窗口初始化void refreshCom(); //刷新串口void tableInit(); //表格初始化void createItemsARow(int rowNum, QByteArray *protocalData); //表格新建一行QString ByteArrayToHexString(QByteArray ba);
private:Ui::Widget *ui;QSerialPort* serialPort;
public slots:void comboBoxClicked(); //comboBox被点击
private slots:void sendData(); //发送串口数据void receiveData(); //接收串口数据void openSerialport(); //串口开启void closeSerialport(); //串口关闭void setBuad(int); //设置波特率void clearRcv(); //清楚接收缓存void on_btnConvert_clicked(); //转换按钮被点击void on_btnClear_clicked(); //清楚转化的按钮被点击void sendProtocalHexData(); //以hex格式发送串口数据void handleSerialError(QSerialPort::SerialPortError serialPortErr); //串口异常捕获
};#endif // WIDGET_Hwidget.cpp
#include widget.h
#include ui_widget.h
#include newcombobox.h
#include algorithmWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);//创建一个定时器用来定时发送QTimer *timer1 new QTimer();timer1-start(1000);connect(timer1,QTimer::timeout,[](){int timed ui-comboBox_timedSend-currentText().toInt();timer1-start(timed);if(ui-checkBox_timedSend-isChecked() true){sendData();}});windowInit();tableInit();serialPort new QSerialPort();serialPortInit();connect(serialPort,SIGNAL(readyRead()),this,SLOT(receiveData()));connect(serialPort,SIGNAL(errorOccurred(QSerialPort::SerialPortError)),this,SLOT(handleSerialError(QSerialPort::SerialPortError)));connect(ui-pushButton_sendData,SIGNAL(clicked()),this,SLOT(sendData()));connect(ui-pushButton_openSerialPort,SIGNAL(clicked()),this,SLOT(openSerialport()));connect(ui-pushButton_closeSerialPort,SIGNAL(clicked()),this,SLOT(closeSerialport()));connect(ui-comboBox_chooseCom,SIGNAL(clicked()),this,SLOT(comboBoxClicked()));connect(ui-pushButton_clearRcv,SIGNAL(clicked()),this,SLOT(clearRcv()));connect(ui-pushButton_convert,SIGNAL(clicked()),this,SLOT(on_btnConvert_clicked()));connect(ui-pushButton_clearConvertData,SIGNAL(clicked()),this,SLOT(on_btnClear_clicked()));connect(ui-pushButton_sendProtocalData,SIGNAL(clicked()),this,SLOT(sendProtocalHexData()));connect(serialPort,SIGNAL(errorOccurred(QSerialPort::SerialPortError)),this,SLOT(handleSerialError(QSerialPort::SerialPortError)));connect(ui-comboBox_setBuad,SIGNAL(activated(int)),this,SLOT(setBuad(int)));
}Widget::~Widget()
{delete ui;
}//串口异常捕获
void Widget::handleSerialError(QSerialPort::SerialPortError serialPortErr)
{if(serialPortErr QSerialPort::ResourceError){QMessageBox::critical(NULL, critical, 设备拔出, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);closeSerialport();}if(serialPortErr QSerialPort::DeviceNotFoundError){QMessageBox::critical(NULL, critical, 找不到串口, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);closeSerialport();}
}void Widget::comboBoxClicked()
{refreshCom();
}void Widget::windowInit()
{ui-pushButton_closeSerialPort-setEnabled(false);ui-pushButton_openSerialPort-setEnabled(false);ui-pushButton_sendData-setEnabled(false);setWindowTitle(tr(串口收发));ui-comboBox_timedSend-addItem(10);ui-comboBox_timedSend-addItem(100);ui-comboBox_timedSend-addItem(1000);ui-comboBox_timedSend-setCurrentIndex(2);
}void Widget::refreshCom()
{//显示串口列表ui-comboBox_chooseCom-clear();foreach(QSerialPortInfo portInfo, QSerialPortInfo::availablePorts())ui-comboBox_chooseCom-addItem(portInfo.portName():portInfo.description());ui-pushButton_openSerialPort-setEnabled(ui-comboBox_chooseCom-count()0); //
}void Widget::serialPortInit(){refreshCom();ui-comboBox_setBuad-addItem(9600);ui-comboBox_setBuad-addItem(115200);ui-comboBox_setBuad-addItem(921600);ui-comboBox_setBuad-setCurrentIndex(1);}void Widget::tableInit()
{QStringList headerText;headerText时间命令1命令2数据;ui-tableWidget-setColumnCount(headerText.size()); //设置表格列数ui-tableWidget-resizeColumnsToContents();for (int i0;iui-tableWidget-columnCount();i){QTableWidgetItem *headerItemnew QTableWidgetItem(headerText.at(i));QFont fontheaderItem-font(); //获取原有字体设置font.setBold(true); //设置为粗体font.setPointSize(10); //字体大小headerItem-setForeground(QBrush(Qt::black)); //设置文字颜色headerItem-setFont(font); //设置字体ui-tableWidget-setHorizontalHeaderItem(i,headerItem); //设置表头单元格的item}ui-tableWidget-setColumnWidth(0, 60);ui-tableWidget-setColumnWidth(1, 50);ui-tableWidget-setColumnWidth(2, 50);ui-tableWidget-setColumnWidth(3, 250);
}//为一行的单元格创建 Items
void Widget::createItemsARow(int rowNum, QByteArray *protocalData)
{uchar preFix 0xA5;uchar crc 0;uchar temp 0;temp static_castuchar(protocalData-at(0));if(static_castuchar(protocalData-at(0)) preFix){for(int i1; iprotocalData-length()-2; i){temp static_castuchar(protocalData-at(i));crc static_castuchar(protocalData-at(i));}temp static_castuchar(protocalData-at(protocalData-length()-2));if(crc ! static_castuchar(protocalData-at(protocalData-length()-2))){return;}uchar len protocalData-at(1);uchar cmd1 protocalData-at(2);uchar cmd2 protocalData-at(3);QByteArray data protocalData-mid(4,len-6);QDateTime curTime QDateTime::currentDateTime();//获取系统现在的时间QString time curTime.toString(hh:mm:ss); //设置显示格式uint8_t str1 static_castuint8_t(cmd1);QString hexStr1 QString(%1).arg(str1, 2, 16, QLatin1Char(0)).toUpper();uint8_t str2 static_castuint8_t(cmd2);QString hexStr2 QString(%1).arg(str2, 2, 16, QLatin1Char(0)).toUpper();QString testdata ByteArrayToHexString(data).toLatin1().toUpper();QTableWidgetItem *item new QTableWidgetItem(time, ctTime);ui-tableWidget-setItem(rowNum, colTime, item);item new QTableWidgetItem(hexStr1, ctCmd1);ui-tableWidget-setItem(rowNum, colCmd1, item);item new QTableWidgetItem(hexStr2, ctCmd2);ui-tableWidget-setItem(rowNum, colCmd2, item);item new QTableWidgetItem(testdata, ctData);ui-tableWidget-setItem(rowNum, colData, item);}auto lastRowIndex ui-tableWidget-rowCount()-1; // 最后一行的索引auto lastModelIndex ui-tableWidget-model()-index(lastRowIndex, 0);ui-tableWidget-scrollTo(lastModelIndex); // 滚动到最后一行
}QString Widget::ByteArrayToHexString(QByteArray ba)
{QDataStream out(ba,QIODevice::ReadWrite); //将str的数据 读到out里面去QString buf;while(!out.atEnd()){qint8 outChar 0;out outChar; //每次一个字节的填充到 outcharQString str QString(%1).arg(outChar0xFF,2,16,QLatin1Char(0)).toUpper() QString( ); //2 字符宽度buf str;}return buf;
}void Widget::sendData()
{QString message ui-lineEdit_sendData-text();if(ui-checkBox_hexSend-isChecked() true){serialPort-write(QByteArray::fromHex(message.toLatin1()));}else{serialPort-write(message.toLatin1());}
}void Widget::receiveData()
{QByteArray message;QString hexMsg;message.append(serialPort-readAll());QDateTime time QDateTime::currentDateTime(); //获取系统现在的时间QString date time.toString(hh:mm:ss); //设置显示格式if(ui-checkBox_hexRcv-isChecked() true){tableRowCnt;ui-tableWidget-setRowCount(tableRowCnt);createItemsARow(tableRowCnt-1,message);hexMsg ByteArrayToHexString(message).toLatin1();ui-textEdit_RecData-append(dateQString(- )hexMsg.toUpper());}else{ui-textEdit_RecData-append(dateQString(- )message);}
}
void Widget::openSerialport()
{ui-pushButton_closeSerialPort-setEnabled(true);ui-pushButton_openSerialPort-setEnabled(false);QListQSerialPortInfo comList QSerialPortInfo::availablePorts();QSerialPortInfo portInfo comList.at(ui-comboBox_chooseCom-currentIndex());serialPort-setPort(portInfo); //设置使用哪个串口if(serialPort-open(QIODevice::ReadWrite) false){QMessageBox::critical(NULL, critical, 找不到串口/串口被占用, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);closeSerialport();}else{serialPort-setBaudRate(QSerialPort::Baud115200);serialPort-setDataBits(QSerialPort::Data8);serialPort-setParity(QSerialPort::NoParity);serialPort-setStopBits(QSerialPort::OneStop);serialPort-setFlowControl(QSerialPort::NoFlowControl);ui-pushButton_sendData-setEnabled(true);}
}void Widget::closeSerialport()
{if(serialPort-isOpen()){serialPort-clear();serialPort-close();}ui-pushButton_closeSerialPort-setEnabled(false);ui-pushButton_openSerialPort-setEnabled(true);
}void Widget::setBuad(int buad)
{QString str ui-comboBox_setBuad-currentText();serialPort-setBaudRate(str.toInt());
}void Widget::clearRcv()
{ui-textEdit_RecData-clear();
}void Widget::on_btnClear_clicked()
{ui-lineEdit_protocalData-clear();
}void Widget::on_btnConvert_clicked()
{ui-lineEdit_protocalData-clear();bool ok;QString str A5;int val1 ui-lineEditCmd1-text().toInt(ok,16); //以十六进制数读入QString str1 QString(%1).arg(val1, 2, 16, QLatin1Char(0));int val2 ui-lineEditCmd2-text().toInt(ok,16); //以十六进制数读入QString str2 QString(%1).arg(val2, 2, 16, QLatin1Char(0));if ((str1.isEmpty())||(str2.isEmpty()))return;int val3 ui-lineEditData-text().toInt(ok,16); //以十六进制数读入QString str3 QString(%1).arg(val3, 2, 16, QLatin1Char(0));uint8_t len 6 static_castuint8_t(str3.length()/2);QString hexStr QString(%1).arg(len, 2, 16, QLatin1Char(0));str.append(hexStr);str.append(str1);str.append(str2);str.append(str3);uint8_t crc;QString tmp;for(int i0; istr3.length(); i2){tmp ui-lineEditData-text()[i];tmp ui-lineEditData-text()[i1];crc tmp.toInt(ok,16);tmp ;}crc len;crc val1;crc val2;QString hexCrc QString(%1).arg(crc, 2, 16, QLatin1Char(0));str.append(hexCrc);str.append(5A);str str.toUpper();ui-lineEdit_protocalData-insert(str);
}void Widget::sendProtocalHexData()
{QString message ui-lineEdit_protocalData-text();serialPort-write(QByteArray::fromHex(message.toLatin1()));
}ui 代码框架概览 演示视频
串口上位机(基本设置/协议收发)演示_哔哩哔哩_bilibili 串口上位机(基本设置/协议收发)演示