发送/接收数据:

比较简单,一些选项可以使用下拉框或者菜单组件来选择都系,这里我个人用的菜单
Nwidget *SP_configWidget = new Nwidget("SP_configWidget");
Nlabel *SP_portLabel = new Nlabel("SP_portLabel");
Nlabel *SP_baudLabel = new Nlabel("SP_baudLabel");
Nlabel *SP_dtbitsLabel = new Nlabel("SP_dtbitsLabel");
Nlabel *SP_stbitsLabel = new Nlabel("SP_stbitsLabel");
Nlabel *SP_ckPlaceLabel = new Nlabel("SP_ckPlaceLabel");
Nlabel *SP_scontrolLabel = new Nlabel("SP_scontrolLabel");
QToolButton *SP_usbportBut = new QToolButton(SP_Widget);
QToolButton *SP_dtplaceBut = new QToolButton(SP_Widget);
QToolButton *SP_baudrateBut = new QToolButton(SP_Widget);
QToolButton *SP_stplaceBut = new QToolButton(SP_Widget);
QToolButton *SP_ckplaceBut = new QToolButton(SP_Widget);
QToolButton *SP_scontrolBut = new QToolButton(SP_Widget);
QMenu *SP_usbPortMenu = new QMenu();
QMenu *SP_baudRateMenu = new QMenu();
QMenu *SP_dtplaceMenu = new QMenu();
QMenu *SP_stplaceMenu = new QMenu();
QMenu *SP_ckplaceMenu = new QMenu();
QMenu *SP_scontrolMenu = new QMenu();
QAction *AS_baudr115200 = new QAction("115200", SP_baudRateMenu);
QAction *AS_baudr57600 = new QAction("57600", SP_baudRateMenu);
QAction *AS_baudr38400 = new QAction("38400", SP_baudRateMenu);
QAction *AS_baudr19200 = new QAction("19200", SP_baudRateMenu);
QAction *AS_baudr9600 = new QAction("9600", SP_baudRateMenu);
QAction *AS_baudr4800 = new QAction("4800", SP_baudRateMenu);
QAction *AS_baudr2400 = new QAction("2400", SP_baudRateMenu);
QAction *AS_baudr1200 = new QAction("1200", SP_baudRateMenu);
QAction *AS_oddParity = new QAction("奇校验", SP_ckplaceMenu);
QAction *AS_evenParity = new QAction("偶校验", SP_ckplaceMenu);
QAction *AS_unParity = new QAction("无校验", SP_ckplaceMenu);
QAction *AS_dtbitsFive = new QAction("bits 5", SP_dtplaceMenu);
QAction *AS_dtbitsSix = new QAction("bits 6", SP_dtplaceMenu);
QAction *AS_dtbitsSeven = new QAction("bits 7", SP_dtplaceMenu);
QAction *AS_dtbitsEight = new QAction("bits 8", SP_dtplaceMenu);
QAction *AS_stbitsOne = new QAction("bits 1", SP_stplaceMenu);
QAction *AS_stbitshalf = new QAction("bits 1.5", SP_stplaceMenu);
QAction *AS_stbitsTwo = new QAction("bits 2", SP_stplaceMenu);
QAction *AS_hardControl = new QAction("硬件控制", SP_scontrolMenu);
QAction *AS_softControl = new QAction("软件控制", SP_scontrolMenu);
QAction *AS_unControl = new QAction("无控制", SP_scontrolMenu);
把菜单放入QToolButton中,连接信号槽
connect(SP_usbPortMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), SerialPort);});
connect(SP_baudRateMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), BaudRate);});
connect(SP_dtplaceMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), DtPlace);});
connect(SP_stplaceMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), StPlace);});
connect(SP_ckplaceMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), CheckPlace);});
connect(SP_scontrolMenu, &QMenu::triggered, this, [this](QAction *AC){SP_serialAttriCfg(AC->text(), Scontrol);});
其中 SP_serialAttriCfg 函数整合了所有选项了,参数:
QString Actext 菜单选择的选项文本 SerialAttribute Attribute 属性
属性枚举:
typedef enum {
SerialPort,
BaudRate,
DtPlace,
StPlace,
Scontrol,
CheckPlace
} SerialAttribute;
接下来是SP_serialAttriCfg函数代码:
void ToolLogicCT::SP_serialAttriCfg(QString Actext, SerialAttribute Attribute){
switch (Attribute) {
case BaudRate:
if (Actext == "115200")
{
SP_sralPort->setBaudRate(QSerialPort::Baud115200);
}
else if (Actext == "57600")
{
SP_sralPort->setBaudRate(QSerialPort::Baud57600);
}
else if (Actext == "38400")
{
SP_sralPort->setBaudRate(QSerialPort::Baud38400);
}
else if (Actext == "19200")
{
SP_sralPort->setBaudRate(QSerialPort::Baud19200);
}
else if (Actext == "9600")
{
SP_sralPort->setBaudRate(QSerialPort::Baud9600);
}
else if (Actext == "4800")
{
SP_sralPort->setBaudRate(QSerialPort::Baud4800);
}
else if (Actext == "2400")
{
SP_sralPort->setBaudRate(QSerialPort::Baud2400);
}
else
{
SP_sralPort->setBaudRate(QSerialPort::Baud1200);
}
RdoMap_Serial["SQL_SRLP_BAUD"] = QString("BaudRate = '%1'").arg(Actext);
SP_baudrateBut->setText(Actext);
break;
case DtPlace:
if (Actext == "bits 5")
{
SP_sralPort->setDataBits(QSerialPort::Data5);
}
else if (Actext == "bits 6")
{
SP_sralPort->setDataBits(QSerialPort::Data6);
}
else if (Actext == "bits 7")
{
SP_sralPort->setDataBits(QSerialPort::Data7);
}
else
{
SP_sralPort->setDataBits(QSerialPort::Data8);
}
SP_dtplaceBut->setText(Actext);
RdoMap_Serial["SQL_SRLP_DTPL"] = QString("DataPlace = '%1'").arg(Actext);
break;
case StPlace:
if (Actext == "bits 1")
{
SP_sralPort->setStopBits(QSerialPort::OneStop);
}
else if (Actext == "bits 1.5")
{
SP_sralPort->setStopBits(QSerialPort::OneAndHalfStop);
}
else
{
SP_sralPort->setStopBits(QSerialPort::TwoStop);
}
SP_stplaceBut->setText(Actext);
RdoMap_Serial["SQL_SRLP_STPL"] = QString("StopPlace = '%1'").arg(Actext);
break;
case Scontrol:
if (Actext == "硬件控制")
{
SP_sralPort->setFlowControl(QSerialPort::HardwareControl);
}
else if (Actext == "软件控制")
{
SP_sralPort->setFlowControl(QSerialPort::SoftwareControl);
}
else
{
SP_sralPort->setFlowControl(QSerialPort::NoFlowControl);
}
SP_scontrolBut->setText(Actext);
RdoMap_Serial["SQL_SRLP_SCTL"] = QString("SControl = '%1'").arg(Actext);
break;
case CheckPlace:
if (Actext == "奇校验")
{
SP_sralPort->setParity(QSerialPort::OddParity);
}
else if (Actext == "偶校验")
{
SP_sralPort->setParity(QSerialPort::EvenParity);
}
else
{
SP_sralPort->setParity(QSerialPort::NoParity);
}
SP_ckplaceBut->setText(Actext);
RdoMap_Serial["SQL_SRLP_PRTY"] = QString("CheckPlace = '%1'").arg(Actext);
break;
case SerialPort:
QString portName = RdoMap_Serial[Actext];
QFontMetrics portNameMetrics(SP_usbPortMenu->font());
qDebug() << portNameMetrics.horizontalAdvance(portName) << SP_usbportBut->width();
if (portNameMetrics.horizontalAdvance(Actext) <= SP_usbportBut->width())
{
SP_usbportBut->setText(Actext);
}
else
{
SP_usbportBut->setText(portName);
}
QSerialPortInfo SP_sralPortInfo(portName);
SP_sralPort->setPort(SP_sralPortInfo);
break;
}
}
可以看到,代码中设置了 比特率、数据位、停止位、校验位、流控制以及串口名
其中串口名在最初切换到工具的时候已经获取了
} else if ( RdoMap_Integer["ViewIndex"] == 3 ) {
PBL_centraStackWidget->setCurrentWidget(SP_Widget);
FL_fileaddBut->setVisible(false);
TR_actionBut->setVisible(false);
AS_assistBut->setVisible(false);
VW_viewcutBut->setText("当前窗口-[串口工具]");
DT_execBut->setText("连接");
DT_scviewBut->setText("连接列表");
DT_rsviewBut->setText("命令列表");
QList<QSerialPortInfo> portInfoList = QSerialPortInfo::availablePorts();
foreach(QSerialPortInfo port, portInfoList)
{
QString SerialInfo = port.description() + " " + port.portName();
RdoMap_Serial[SerialInfo] = port.portName();
SPActionList.append(new QAction(SerialInfo, SP_usbPortMenu));
}
SP_usbPortMenu->addActions(SPActionList);
QStringList i = RdoMap_Serial.keys();
SP_usbportBut->setText(i[0]);
RdoMap_String["FunctionName"] = "SerialCTTools";
SerialDelayCheckTimer->start();
SP_setToolmenuActionAdjustSize(SP_usbportBut);
SP_setToolmenuActionAdjustSize(SP_baudrateBut);
SP_setToolmenuActionAdjustSize(SP_dtplaceBut);
SP_setToolmenuActionAdjustSize(SP_stplaceBut);
SP_setToolmenuActionAdjustSize(SP_ckplaceBut);
SP_setToolmenuActionAdjustSize(SP_scontrolBut);
主要部分是QSerialPortInfo::availablePorts()列表中的 port.portName(),在后续的打开串口中就需要用到这个端口名了,根据所选项获取对应的保存好的端口名,设置端口

打开端口
void ToolLogicBT::DT_ExecButClick(){
if (RdoMap_String["FunctionName"] == "SerialCTTools" && !RdoMap_Switch["SerialState"])
{
if (SP_sralPort->open(QIODevice::ReadWrite))
{
DT_execBut->setText("连接成功");
RdoMap_Switch["SerialState"] = true;
SP_sralPort->setRequestToSend(true);
SP_sralPort->setBreakEnabled(true);
SP_sralPort->setDataTerminalReady(true);
}
else
{
DT_execBut->setText("连接失败");
RdoMap_Switch["SerialState"] = false;
}
}
else
{
SP_sralPort->close();
RdoMap_Switch["SerialState"] = false;
DT_execBut->setText("连接断开");
}
}
这时候需要把串口数据获取并显示到文本框中,所以需要连接信号槽,获取到串口信息并给它加上时间,焦点,获取部分就写好了。
connect(SP_sralPort, &QSerialPort::readyRead, this, &SignalTool::SP_FollowScEdit);
void ToolLogicCT::SP_FollowScEdit(){
QString DateTimeFormat = "hh:mm:ss";
QString FORMATDATE = QDateTime::currentDateTime().toString(DateTimeFormat);
QString TimeStemp = QString("
[%1]->").arg(FORMATDATE);
QStringList serialInfoList = QString(SP_sralPort->readAll()).split("
").filter(QRegularExpression("\w+"));
QString AddtimeStemp = serialInfoList.join(TimeStemp);
SP_serialInfoEdit->append(TimeStemp + AddtimeStemp);
QTextCursor Cursor = SP_serialInfoEdit->textCursor();
Cursor.movePosition(QTextCursor::End);
SP_serialInfoEdit->setTextCursor(Cursor);
}
接下来是发送信息部分,发送串口数据,比如命令往往是需要 加回车换行的
而write函数中是没有这部分代码的,仅仅是发送。因此,需要设备收到命令并执行的话还需要加上回车换行,代码:
connect(SP_sendBut, &QPushButton::clicked, this, [&]()
{
QByteArray orderCode = SP_orderEdit->text().toLocal8Bit();
SP_sralPort->clear();
orderCode.append("
");
qint64 exec = SP_sralPort->write(orderCode);
if (exec >= 0)
{
SP_sralPort->flush();
SP_sralPort->waitForBytesWritten(10);
};
});
基本功能就是这样了,并不复杂,其他一些功能怎么方便怎么加就好了