|
|
@@ -1,263 +0,0 @@ |
|
|
|
#include "serialportmanager.h" |
|
|
|
#include <QSerialPortInfo> |
|
|
|
#include <QVBoxLayout> |
|
|
|
#include <QHBoxLayout> |
|
|
|
#include <QGroupBox> |
|
|
|
#include <QMessageBox> |
|
|
|
#include <QDebug> |
|
|
|
|
|
|
|
SerialPortManager::SerialPortManager(QWidget *parent) |
|
|
|
: QDialog(parent), m_serial(new QSerialPort(this)) |
|
|
|
{ |
|
|
|
setWindowTitle("串口连接设置"); |
|
|
|
setFixedSize(450,200); |
|
|
|
|
|
|
|
// 连接串口信号 |
|
|
|
connect(m_serial, &QSerialPort::readyRead, this, &SerialPortManager::handleReadyRead); |
|
|
|
connect(m_serial, &QSerialPort::errorOccurred, this, &SerialPortManager::handleError); |
|
|
|
|
|
|
|
// 主布局 |
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout(this); |
|
|
|
|
|
|
|
// 创建单个GroupBox - 串口参数设置 |
|
|
|
QGroupBox *settingsGroup = new QGroupBox("串口参数设置", this); |
|
|
|
QFormLayout *formLayout = new QFormLayout(settingsGroup); |
|
|
|
|
|
|
|
// 串口选择行 |
|
|
|
m_portComboBox = new QComboBox(this); |
|
|
|
QPushButton *refreshButton = new QPushButton("刷新", this); |
|
|
|
QHBoxLayout *portComboLayout = new QHBoxLayout; |
|
|
|
portComboLayout->addWidget(m_portComboBox, 5); |
|
|
|
portComboLayout->addWidget(refreshButton, 1); |
|
|
|
formLayout->addRow("串口:", portComboLayout); |
|
|
|
|
|
|
|
// 波特率选择行 |
|
|
|
m_baudComboBox = new QComboBox(this); |
|
|
|
populateBaudRates(); |
|
|
|
formLayout->addRow("波特率:", m_baudComboBox); |
|
|
|
|
|
|
|
// 奇偶校验选择行 |
|
|
|
m_parityComboBox = new QComboBox(this); |
|
|
|
populateParities(); |
|
|
|
formLayout->addRow("奇偶校验:", m_parityComboBox); |
|
|
|
|
|
|
|
// 从站地址行 |
|
|
|
m_stationSpinBox = new QSpinBox(this); |
|
|
|
m_stationSpinBox->setRange(1, 247); |
|
|
|
m_stationSpinBox->setValue(1); |
|
|
|
formLayout->addRow("从站地址:", m_stationSpinBox); |
|
|
|
|
|
|
|
// 添加到主布局 |
|
|
|
mainLayout->addWidget(settingsGroup); |
|
|
|
|
|
|
|
// 按钮区域 |
|
|
|
QHBoxLayout *buttonLayout = new QHBoxLayout; |
|
|
|
m_connectBtn = new QPushButton("连接", this); |
|
|
|
QPushButton *cancelButton = new QPushButton("取消", this); |
|
|
|
|
|
|
|
// 状态标签 |
|
|
|
m_statusLabel = new QLabel("状态: 未连接", this); |
|
|
|
m_statusLabel->setStyleSheet("QLabel { color: red; }"); |
|
|
|
|
|
|
|
buttonLayout->addWidget(m_statusLabel); |
|
|
|
buttonLayout->addStretch(); |
|
|
|
buttonLayout->addWidget(m_connectBtn); |
|
|
|
buttonLayout->addWidget(cancelButton); |
|
|
|
|
|
|
|
// 添加到主布局 |
|
|
|
mainLayout->addLayout(buttonLayout); |
|
|
|
|
|
|
|
// 连接信号 |
|
|
|
connect(refreshButton, &QPushButton::clicked, this, &SerialPortManager::refreshPorts); |
|
|
|
connect(m_connectBtn, &QPushButton::clicked, this, &SerialPortManager::onConnectClicked); |
|
|
|
connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); |
|
|
|
|
|
|
|
// 初始刷新端口 |
|
|
|
refreshPorts(); |
|
|
|
} |
|
|
|
|
|
|
|
SerialPortManager::~SerialPortManager() |
|
|
|
{ |
|
|
|
if (m_serial->isOpen()) { |
|
|
|
m_serial->close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 串口操作接口实现 |
|
|
|
bool SerialPortManager::isOpen() const |
|
|
|
{ |
|
|
|
return m_serial->isOpen(); |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::openSerialPort() |
|
|
|
{ |
|
|
|
if (!m_serial->isOpen()) { |
|
|
|
onConnectClicked(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::closeSerialPort() |
|
|
|
{ |
|
|
|
if (m_serial->isOpen()) { |
|
|
|
m_serial->close(); |
|
|
|
updateConnectionState(false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
QByteArray SerialPortManager::readAll() |
|
|
|
{ |
|
|
|
return m_serial->readAll(); |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::write(const QByteArray &data) |
|
|
|
{ |
|
|
|
if (m_serial->isOpen()) { |
|
|
|
m_serial->write(data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 连接按钮槽函数 |
|
|
|
void SerialPortManager::onConnectClicked() |
|
|
|
{ |
|
|
|
if (m_serial->isOpen()) { |
|
|
|
// 如果已连接,则断开 |
|
|
|
m_serial->close(); |
|
|
|
updateConnectionState(false); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取配置 |
|
|
|
QString portName = m_portComboBox->currentData().toString(); |
|
|
|
int baudRate = m_baudComboBox->currentData().toInt(); |
|
|
|
QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(m_parityComboBox->currentData().toInt()); |
|
|
|
|
|
|
|
if (portName.isEmpty()) { |
|
|
|
QMessageBox::warning(this, "错误", "请选择有效的串口"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 配置串口 |
|
|
|
m_serial->setPortName(portName); |
|
|
|
m_serial->setBaudRate(baudRate); |
|
|
|
m_serial->setDataBits(QSerialPort::Data8); |
|
|
|
m_serial->setParity(parity); |
|
|
|
m_serial->setStopBits(QSerialPort::OneStop); |
|
|
|
|
|
|
|
if (m_serial->open(QIODevice::ReadWrite)) |
|
|
|
{ |
|
|
|
updateConnectionState(true); |
|
|
|
QString logMsg = QString("串口连接成功: %1, %2 bps, 从站地址: %3") |
|
|
|
.arg(portName) |
|
|
|
.arg(baudRate) |
|
|
|
.arg(m_stationSpinBox->value()); |
|
|
|
emit logMessage(logMsg); // 发送统一日志 |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
QString errorMsg = QString("串口连接失败: %1").arg(m_serial->errorString()); |
|
|
|
emit logMessage(errorMsg); // 发送统一日志 |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 更新连接状态 |
|
|
|
void SerialPortManager::updateConnectionState(bool connected) |
|
|
|
{ |
|
|
|
if (connected) { |
|
|
|
m_connectBtn->setText("断开"); |
|
|
|
m_statusLabel->setText("状态: 已连接"); |
|
|
|
m_statusLabel->setStyleSheet("QLabel { color: green; }"); |
|
|
|
} else { |
|
|
|
m_connectBtn->setText("连接"); |
|
|
|
m_statusLabel->setText("状态: 未连接"); |
|
|
|
m_statusLabel->setStyleSheet("QLabel { color: red; }"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 数据接收处理 |
|
|
|
void SerialPortManager::handleReadyRead() |
|
|
|
{ |
|
|
|
QByteArray data = m_serial->readAll(); |
|
|
|
if (!data.isEmpty()) { |
|
|
|
QString hexString = data.toHex().toUpper(); // 转换为大写的十六进制 |
|
|
|
emit logMessage("接收: " + hexString); // 发送统一日志 |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 错误处理 |
|
|
|
void SerialPortManager::handleError(QSerialPort::SerialPortError error) |
|
|
|
{ |
|
|
|
if (error != QSerialPort::NoError) |
|
|
|
{ |
|
|
|
QString errorMsg = QString("串口错误: %1").arg(m_serial->errorString()); |
|
|
|
emit logMessage(errorMsg); // 发送统一日志 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::populateBaudRates() |
|
|
|
{ |
|
|
|
m_baudComboBox->clear(); |
|
|
|
m_baudComboBox->addItem("4800", QSerialPort::Baud4800); |
|
|
|
m_baudComboBox->addItem("9600", QSerialPort::Baud9600); |
|
|
|
m_baudComboBox->addItem("19200", QSerialPort::Baud19200); |
|
|
|
m_baudComboBox->addItem("38400", QSerialPort::Baud38400); |
|
|
|
m_baudComboBox->addItem("57600", QSerialPort::Baud57600); |
|
|
|
m_baudComboBox->addItem("115200", QSerialPort::Baud115200); |
|
|
|
m_baudComboBox->setCurrentIndex(1); // 默认9600 |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::populateParities() |
|
|
|
{ |
|
|
|
m_parityComboBox->clear(); |
|
|
|
m_parityComboBox->addItem("无校验", QSerialPort::NoParity); |
|
|
|
m_parityComboBox->addItem("奇校验", QSerialPort::OddParity); |
|
|
|
m_parityComboBox->addItem("偶校验", QSerialPort::EvenParity); |
|
|
|
m_parityComboBox->setCurrentIndex(0); // 默认无校验 |
|
|
|
} |
|
|
|
|
|
|
|
void SerialPortManager::refreshPorts() |
|
|
|
{ |
|
|
|
m_portComboBox->clear(); |
|
|
|
const auto ports = QSerialPortInfo::availablePorts(); |
|
|
|
|
|
|
|
for (const QSerialPortInfo &port : ports) { |
|
|
|
QString description = port.description(); |
|
|
|
if (description.isEmpty()) description = "未知设备"; |
|
|
|
|
|
|
|
QString itemText = QString("%1 (%2)") |
|
|
|
.arg(port.portName()) |
|
|
|
.arg(description); |
|
|
|
|
|
|
|
m_portComboBox->addItem(itemText, port.portName()); |
|
|
|
} |
|
|
|
if (ports.isEmpty()) |
|
|
|
{ |
|
|
|
m_portComboBox->addItem("无可用端口", ""); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
QString SerialPortManager::portName() const |
|
|
|
{ |
|
|
|
return m_portComboBox->currentData().toString(); |
|
|
|
} |
|
|
|
|
|
|
|
int SerialPortManager::baudRate() const |
|
|
|
{ |
|
|
|
return m_baudComboBox->currentData().toInt(); |
|
|
|
} |
|
|
|
|
|
|
|
QSerialPort::Parity SerialPortManager::parity() const |
|
|
|
{ |
|
|
|
return static_cast<QSerialPort::Parity>(m_parityComboBox->currentData().toInt()); |
|
|
|
} |
|
|
|
|
|
|
|
QSerialPort::StopBits SerialPortManager::stopBits() const |
|
|
|
{ |
|
|
|
return QSerialPort::OneStop; |
|
|
|
} |
|
|
|
|
|
|
|
int SerialPortManager::stationAddress() const |
|
|
|
{ |
|
|
|
return m_stationSpinBox->value(); |
|
|
|
} |