/*Copyright © 2017 Hasan Yavuz ÖzderyaThis file is part of serialplot.serialplot is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.serialplot is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with serialplot. If not, see <http://www.gnu.org/licenses/>.*/#include "portcontrol.h"#include "ui_portcontrol.h"#include <QSerialPortInfo>#include <QKeySequence>#include <QLabel>#include <QMap>#include <QtDebug>#include "setting_defines.h"#include "utils.h"#define TBPORTLIST_MINWIDTH (200)// setting mappingsconst QMap<QSerialPort::Parity, QString> paritySettingMap({{QSerialPort::NoParity, "none"},{QSerialPort::OddParity, "odd"},{QSerialPort::EvenParity, "even"},});PortControl::PortControl(QSerialPort* port, QWidget* parent) :QWidget(parent),ui(new Ui::PortControl),portToolBar("Port Toolbar"),openAction("Open", this),loadPortListAction("↺", this){ui->setupUi(this);serialPort = port;connect(serialPort, SIGNAL(error(QSerialPort::SerialPortError)),this, SLOT(onPortError(QSerialPort::SerialPortError)));// setup actionsopenAction.setCheckable(true);openAction.setShortcut(QKeySequence("F12"));openAction.setToolTip("Open Port");QObject::connect(&openAction, &QAction::triggered,this, &PortControl::openActionTriggered);loadPortListAction.setToolTip("Reload port list");QObject::connect(&loadPortListAction, &QAction::triggered,[this](bool checked){loadPortList();});// setup toolbarportToolBar.addWidget(&tbPortList);portToolBar.addAction(&loadPortListAction);portToolBar.addAction(&openAction);// setup port selection widgetstbPortList.setMinimumWidth(TBPORTLIST_MINWIDTH);tbPortList.setModel(&portList);ui->cbPortList->setModel(&portList);QObject::connect(ui->cbPortList,SELECT<int>::OVERLOAD_OF(&QComboBox::activated),this, &PortControl::onCbPortListActivated);QObject::connect(&tbPortList,SELECT<int>::OVERLOAD_OF(&QComboBox::activated),this, &PortControl::onTbPortListActivated);QObject::connect(ui->cbPortList,SELECT<const QString&>::OVERLOAD_OF(&QComboBox::activated),this, &PortControl::selectPort);QObject::connect(&tbPortList,SELECT<const QString&>::OVERLOAD_OF(&QComboBox::activated),this, &PortControl::selectPort);// setup buttonsui->pbOpenPort->setDefaultAction(&openAction);ui->pbReloadPorts->setDefaultAction(&loadPortListAction);// setup baud rate selection widgetQObject::connect(ui->cbBaudRate,SELECT<const QString&>::OVERLOAD_OF(&QComboBox::activated),this, &PortControl::selectBaudRate);// setup parity selection buttonsparityButtons.addButton(ui->rbNoParity, (int) QSerialPort::NoParity);parityButtons.addButton(ui->rbEvenParity, (int) QSerialPort::EvenParity);parityButtons.addButton(ui->rbOddParity, (int) QSerialPort::OddParity);QObject::connect(&parityButtons,SELECT<int>::OVERLOAD_OF(&QButtonGroup::buttonClicked),this, &PortControl::selectParity);// setup data bits selection buttonsdataBitsButtons.addButton(ui->rb8Bits, (int) QSerialPort::Data8);dataBitsButtons.addButton(ui->rb7Bits, (int) QSerialPort::Data7);dataBitsButtons.addButton(ui->rb6Bits, (int) QSerialPort::Data6);dataBitsButtons.addButton(ui->rb5Bits, (int) QSerialPort::Data5);QObject::connect(&dataBitsButtons,SELECT<int>::OVERLOAD_OF(&QButtonGroup::buttonClicked),this, &PortControl::selectDataBits);// setup stop bits selection buttonsstopBitsButtons.addButton(ui->rb1StopBit, (int) QSerialPort::OneStop);stopBitsButtons.addButton(ui->rb2StopBit, (int) QSerialPort::TwoStop);QObject::connect(&stopBitsButtons,SELECT<int>::OVERLOAD_OF(&QButtonGroup::buttonClicked),this, &PortControl::selectStopBits);// setup flow control selection buttonsflowControlButtons.addButton(ui->rbNoFlowControl,(int) QSerialPort::NoFlowControl);flowControlButtons.addButton(ui->rbHardwareControl,(int) QSerialPort::HardwareControl);flowControlButtons.addButton(ui->rbSoftwareControl,(int) QSerialPort::SoftwareControl);QObject::connect(&flowControlButtons,SELECT<int>::OVERLOAD_OF(&QButtonGroup::buttonClicked),this, &PortControl::selectFlowControl);// initialize signal ledsui->ledDTR->setOn(true);ui->ledRTS->setOn(true);// connect output signalsconnect(ui->pbDTR, &QPushButton::clicked, [this](){// toggle DTRui->ledDTR->toggle();if (serialPort->isOpen()){serialPort->setDataTerminalReady(ui->ledDTR->isOn());}});connect(ui->pbRTS, &QPushButton::clicked, [this](){// toggle RTSui->ledRTS->toggle();if (serialPort->isOpen()){serialPort->setRequestToSend(ui->ledRTS->isOn());}});// setup pin update ledsui->ledDCD->setColor(Qt::yellow);ui->ledDSR->setColor(Qt::yellow);ui->ledRI->setColor(Qt::yellow);ui->ledCTS->setColor(Qt::yellow);pinUpdateTimer.setInterval(1000); // msconnect(&pinUpdateTimer, &QTimer::timeout, this, &PortControl::updatePinLeds);loadPortList();loadBaudRateList();ui->cbBaudRate->setCurrentIndex(ui->cbBaudRate->findText("9600"));}PortControl::~PortControl(){delete ui;}void PortControl::loadPortList(){QString currentSelection = ui->cbPortList->currentData(PortNameRole).toString();portList.loadPortList();int index = portList.indexOf(currentSelection);if (index >= 0){ui->cbPortList->setCurrentIndex(index);tbPortList.setCurrentIndex(index);}}void PortControl::loadBaudRateList(){ui->cbBaudRate->clear();for (auto baudRate : QSerialPortInfo::standardBaudRates()){ui->cbBaudRate->addItem(QString::number(baudRate));}}void PortControl::selectBaudRate(QString baudRate){if (serialPort->isOpen()){if (!serialPort->setBaudRate(baudRate.toInt())){qCritical() << "Can't set baud rate!";}}}void PortControl::selectParity(int parity){if (serialPort->isOpen()){if(!serialPort->setParity((QSerialPort::Parity) parity)){qCritical() << "Can't set parity option!";}}}void PortControl::selectDataBits(int dataBits){if (serialPort->isOpen()){if(!serialPort->setDataBits((QSerialPort::DataBits) dataBits)){qCritical() << "Can't set numer of data bits!";}}}void PortControl::selectStopBits(int stopBits){if (serialPort->isOpen()){if(!serialPort->setStopBits((QSerialPort::StopBits) stopBits)){qCritical() << "Can't set number of stop bits!";}}}void PortControl::selectFlowControl(int flowControl){if (serialPort->isOpen()){if(!serialPort->setFlowControl((QSerialPort::FlowControl) flowControl)){qCritical() << "Can't set flow control option!";}}}void PortControl::togglePort(){if (serialPort->isOpen()){pinUpdateTimer.stop();serialPort->close();qDebug() << "Closed port:" << serialPort->portName();emit portToggled(false);}else{// we get the port name from the edit text, which may not be// in the portList if user hasn't pressed Enter// Also note that, portText may not be the `portName`QString portText = ui->cbPortList->currentText();QString portName;int portIndex = portList.indexOf(portText);if (portIndex < 0) // not in list, add to model and update the selections{portList.appendRow(new PortListItem(portText));ui->cbPortList->setCurrentIndex(portList.rowCount()-1);tbPortList.setCurrentIndex(portList.rowCount()-1);portName = portText;}else{// get the port name from the data fieldportName = static_cast<PortListItem*>(portList.item(portIndex))->portName();}serialPort->setPortName(ui->cbPortList->currentData(PortNameRole).toString());// open portif (serialPort->open(QIODevice::ReadWrite)){// set port settingsselectBaudRate(ui->cbBaudRate->currentText());selectParity((QSerialPort::Parity) parityButtons.checkedId());selectDataBits((QSerialPort::DataBits) dataBitsButtons.checkedId());selectStopBits((QSerialPort::StopBits) stopBitsButtons.checkedId());selectFlowControl((QSerialPort::FlowControl) flowControlButtons.checkedId());// set output signalsserialPort->setDataTerminalReady(ui->ledDTR->isOn());serialPort->setRequestToSend(ui->ledRTS->isOn());// update pin signalsupdatePinLeds();pinUpdateTimer.start();qDebug() << "Opened port:" << serialPort->portName();emit portToggled(true);}}openAction.setChecked(serialPort->isOpen());}void PortControl::selectPort(QString portName){// portName may be coming from comboboxportName = portName.split(" ")[0];// has selection actually changedif (portName != serialPort->portName()){// if another port is already open, close it by togglingif (serialPort->isOpen()){togglePort();// open new selection by togglingtogglePort();}}}QString PortControl::selectedPortName(){QString portText = ui->cbPortList->currentText();int portIndex = portList.indexOf(portText);if (portIndex < 0) // not in the list yet{// return the displayed name as port namereturn portText;}else{// get the port name from the 'port list'return static_cast<PortListItem*>(portList.item(portIndex))->portName();}}QToolBar* PortControl::toolBar(){return &portToolBar;}void PortControl::openActionTriggered(bool checked){togglePort();}void PortControl::onCbPortListActivated(int index){tbPortList.setCurrentIndex(index);}void PortControl::onTbPortListActivated(int index){ui->cbPortList->setCurrentIndex(index);}void PortControl::onPortError(QSerialPort::SerialPortError error){switch(error){case QSerialPort::NoError :break;case QSerialPort::ResourceError :qWarning() << "Port error: resource unavaliable; most likely device removed.";if (serialPort->isOpen()){qWarning() << "Closing port on resource error: " << serialPort->portName();togglePort();}loadPortList();break;case QSerialPort::DeviceNotFoundError:qCritical() << "Device doesn't exists: " << serialPort->portName();break;case QSerialPort::PermissionError:qCritical() << "Permission denied. Either you don't have \required privileges or device is already opened by another process.";break;case QSerialPort::OpenError:qWarning() << "Device is already opened!";break;case QSerialPort::NotOpenError:qCritical() << "Device is not open!";break;case QSerialPort::ParityError:qCritical() << "Parity error detected.";break;case QSerialPort::FramingError:qCritical() << "Framing error detected.";break;case QSerialPort::BreakConditionError:qCritical() << "Break condition is detected.";break;case QSerialPort::WriteError:qCritical() << "An error occurred while writing data.";break;case QSerialPort::ReadError:qCritical() << "An error occurred while reading data.";break;case QSerialPort::UnsupportedOperationError:qCritical() << "Operation is not supported.";break;case QSerialPort::TimeoutError:qCritical() << "A timeout error occurred.";break;case QSerialPort::UnknownError:qCritical() << "Unknown error! Error: " << serialPort->errorString();break;default:qCritical() << "Unhandled port error: " << error;break;}}void PortControl::updatePinLeds(void){auto pins = serialPort->pinoutSignals();ui->ledDCD->setOn(pins & QSerialPort::DataCarrierDetectSignal);ui->ledDSR->setOn(pins & QSerialPort::DataSetReadySignal);ui->ledRI->setOn(pins & QSerialPort::RingIndicatorSignal);ui->ledCTS->setOn(pins & QSerialPort::ClearToSendSignal);}QString PortControl::currentParityText(){return paritySettingMap.value((QSerialPort::Parity) parityButtons.checkedId());}QString PortControl::currentFlowControlText(){if (flowControlButtons.checkedId() == QSerialPort::HardwareControl){return "hardware";}else if (flowControlButtons.checkedId() == QSerialPort::SoftwareControl){return "software";}else // no parity{return "none";}}void PortControl::saveSettings(QSettings* settings){settings->beginGroup(SettingGroup_Port);settings->setValue(SG_Port_SelectedPort, selectedPortName());settings->setValue(SG_Port_BaudRate, ui->cbBaudRate->currentText());settings->setValue(SG_Port_Parity, currentParityText());settings->setValue(SG_Port_DataBits, dataBitsButtons.checkedId());settings->setValue(SG_Port_StopBits, stopBitsButtons.checkedId());settings->setValue(SG_Port_FlowControl, currentFlowControlText());settings->endGroup();}void PortControl::loadSettings(QSettings* settings){// make sure the port is closedif (serialPort->isOpen()) togglePort();settings->beginGroup(SettingGroup_Port);// set port name if it exists in the current list otherwise ignoreQString portName = settings->value(SG_Port_SelectedPort, QString()).toString();if (!portName.isEmpty()){int index = portList.indexOfName(portName);if (index > -1) ui->cbPortList->setCurrentIndex(index);}// load baud rate setting if it exists in baud rate listQString baudSetting = settings->value(SG_Port_BaudRate, ui->cbBaudRate->currentText()).toString();int baudIndex = ui->cbBaudRate->findText(baudSetting);if (baudIndex > -1) ui->cbBaudRate->setCurrentIndex(baudIndex);// load parity settingQString parityText =settings->value(SG_Port_Parity, currentParityText()).toString();QSerialPort::Parity paritySetting = paritySettingMap.key(parityText, (QSerialPort::Parity) parityButtons.checkedId());parityButtons.button(paritySetting)->setChecked(true);// load number of bitsint dataBits = settings->value(SG_Port_Parity, dataBitsButtons.checkedId()).toInt();if (dataBits >=5 && dataBits <= 8){dataBitsButtons.button((QSerialPort::DataBits) dataBits)->setChecked(true);}// load stop bitsint stopBits = settings->value(SG_Port_StopBits, stopBitsButtons.checkedId()).toInt();if (stopBits == QSerialPort::OneStop){ui->rb1StopBit->setChecked(true);}else if (stopBits == QSerialPort::TwoStop){ui->rb2StopBit->setChecked(true);}// load flow controlQString flowControlSetting =settings->value(SG_Port_FlowControl, currentFlowControlText()).toString();if (flowControlSetting == "hardware"){ui->rbHardwareControl->setChecked(true);}else if (flowControlSetting == "software"){ui->rbSoftwareControl->setChecked(true);}else{ui->rbNoFlowControl->setChecked(true);}settings->endGroup();}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。