上一章:QT5自制串口助手(4)数据收发
现在只差串口的HEX发送及HEX显示了。
- HEX发送
点击HEX发送控件,在右下角修改其属性,取消自动互斥。(可以试一下不取消会怎么样)
然后右键创建槽函数。在选择了HEX发送的时候,我把状态赋给一个全局变量。
全局变量定义在:
然后我们在发送的时候去判断HexSend这个变量。
因为我们取到控件SENDDATA的内容其实是字符串,比如你要发AA,其实是“AA”,所以要把字符串‘A’转成16进制A,高低4位拼接为一个8位的数。而且要把字符串内所有空格删除掉。
使用函数:
记得添加声明:
发送虽然可以了,但是我们还需要限定输入框只能输入0 ~ 9和A ~ F和空格,否则可能出现问题。
右键输入框,选择槽函数textChanged,这个函数会在输入框内内容变化时触发。
注意这里判断的是倒数第二个字符,也就是输入框改变后新输入的字符,最后一个字符是结束符0。
- 添加接收
同样的,在选择HEX接收时我们把它传给变量
显示时判断就行了:
源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
HexDis = false;
HexSend = false;
setWindowTitle(tr("串口工具"));
my_serialport = new QSerialPort();
my_serialportlist = getPortNameList();
ui->COMNUM->addItems(my_serialportlist);
QStringList baud;
baud<<"2400"<<"4800"<<"9600"<<"115200";
ui->BAUD->addItems(baud);
myTimer = new QTimer(this);
myTimer->setInterval(ui->FRAMEDELAY->text().toInt());
connect(myTimer,SIGNAL(timeout()),this,SLOT(timeoutslot()));
ui->DATA->setReadOnly(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
QStringList MainWindow::getPortNameList()
{
QStringList my_serialPortName;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
my_serialPortName << info.portName();
//qDebug()<<"serialPortName:"<<info.portName();
}
return my_serialPortName;
}
void MainWindow::on_OPENSERIAL_clicked()
{
if(my_serialport->isOpen())
{
my_serialport->clear();
my_serialport->close();
myTimer->stop();
ui->OPENSERIAL->setText("打开串口");
}
else
{
my_serialport->setPortName(ui->COMNUM->currentText());
if(!my_serialport->open(QIODevice::ReadWrite))
{
QMessageBox::information(this,tr("INFO"),tr("打开失败!"));
ui->OPENSERIAL->setText("打开串口");
//qDebug()<<"打开失败!";
}
ui->OPENSERIAL->setText("关闭串口");
QMessageBox::information(this,tr("INFO"),tr("打开成功!"));
//qDebug()<<"打开成功!";
//qDebug()<<(ui->BAUD->currentText().toInt());
switch(ui->BAUD->currentText().toInt())
{
case 2400:
my_serialport->setBaudRate(QSerialPort::Baud2400,QSerialPort::AllDirections);
break;
case 4800:
my_serialport->setBaudRate(QSerialPort::Baud4800,QSerialPort::AllDirections);
break;
case 9600:
my_serialport->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);
break;
case 115200:
my_serialport->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
break;
}
my_serialport->setDataBits(QSerialPort::Data8);
my_serialport->setFlowControl(QSerialPort::NoFlowControl);
my_serialport->setParity(QSerialPort::NoParity);
my_serialport->setStopBits(QSerialPort::OneStop);
//connect(my_serialport,SIGNAL(readyRead),this,SLOT(ReadData));
myTimer->start();
}
}
void MainWindow::timeoutslot()
{
QByteArray readdata;
readdata = my_serialport->readAll();
if(!readdata.isEmpty())
{
if(HexDis)
{
ui->DATA->append("RX: ");
for(int i=0;i<readdata.size();i++)
{
ui->DATA->insertPlainText((readdata.toHex().mid(i*2,2))+" ");
}
}
else
ui->DATA->append("RX: "+readdata);
//qDebug()<<readdata;
}
}
void MainWindow::on_FRAMEDELAY_editingFinished()
{
if(ui->FRAMEDELAY->text().toInt())
myTimer->setInterval(ui->FRAMEDELAY->text().toInt());
else
{
ui->FRAMEDELAY->setText("20");
myTimer->setInterval(20);
}
//qDebug()<<ui->FRAMEDELAY->text().toInt();
}
quint8 MainWindow::StringToHex(char str)
{
if(str<='9'&&str>='0')
{
return (str-'0');
}
else if(str>='A'&&str<='F')
{
return (str-'A'+10);
}
else if(str>='a'&&str<='f')
{
return (str-'a'+10);
}
return 0xFF;
}
void MainWindow::on_SEND_clicked()
{
if(my_serialport->isOpen())
{
if(HexSend)
{
//qDebug()<<ui->SENDDATA->toPlainText().remove(QRegExp("\\s"));
QString tmpStr = ui->SENDDATA->toPlainText().remove(QRegExp("\\s"));
QByteArray tmpArray;
for(int i=0;i<tmpStr.size()/2;i++)
{
//qDebug()<<tmp.mid(i*2,2).toLatin1();
tmpArray[i] = StringToHex(tmpStr[i*2].toLatin1())*16+StringToHex(tmpStr[i*2+1].toLatin1());
}
my_serialport->write(tmpArray);
}
else
my_serialport->write(ui->SENDDATA->toPlainText().toUtf8());
ui->DATA->append("TX: "+ui->SENDDATA->toPlainText());
}
else
QMessageBox::warning(this,tr("Error"),tr("先打开串口"));
}
void MainWindow::on_CLEAR_clicked()
{
ui->DATA->clear();
}
void MainWindow::on_HEXDIS_clicked(bool checked)
{
//qDebug()<<checked;
ui->DATA->clear();
HexDis = checked;
}
void MainWindow::on_HEXSEND_clicked(bool checked)
{
//qDebug()<<checked;
HexSend = checked;
ui->SENDDATA->clear();
}
void MainWindow::on_SENDDATA_textChanged()
{
if(HexSend)
{
if(!ui->SENDDATA->toPlainText().isEmpty())
{
if(((*(ui->SENDDATA->toPlainText().end()-1)>='0')&&(*(ui->SENDDATA->toPlainText().end()-1)<='9'))||((*(ui->SENDDATA->toPlainText().end()-1)>='A')&&(*(ui->SENDDATA->toPlainText().end()-1)<='F'))||(*(ui->SENDDATA->toPlainText().end()-1)==' '))
{
}
else
{
ui->SENDDATA->clear();
QMessageBox::warning(this,tr("Error"),tr("只能输入0-9 / A-F"));
}
}
}
//qDebug()<<ui->SENDDATA->toPlainText();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QTime>
#include <QTimer>
#include <QMessageBox>
#include <QStringListModel>
#include <QTextCodec>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_OPENSERIAL_clicked();
void on_FRAMEDELAY_editingFinished();
void on_SEND_clicked();
void timeoutslot();
void on_CLEAR_clicked();
void on_HEXDIS_clicked(bool checked);
void on_HEXSEND_clicked(bool checked);
void on_SENDDATA_textChanged();
private:
Ui::MainWindow *ui;
QSerialPort *my_serialport;
QStringList my_serialportlist;
QStringList getPortNameList();
QTimer *myTimer;
bool HexDis;
bool HexSend;
quint8 StringToHex(char str);
};
#endif // MAINWINDOW_H
都看到这里了不点个赞吗
git下载地址:
https://github.com/CXsCode/QT5-.git