|
- #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();
- }
|