#include "serialportmanager.h" #include #include #include #include #include #include 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(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(m_parityComboBox->currentData().toInt()); } QSerialPort::StopBits SerialPortManager::stopBits() const { return QSerialPort::OneStop; } int SerialPortManager::stationAddress() const { return m_stationSpinBox->value(); }