From 1f3dffdeba7ce9768610d63cfec0c8a30b60b9a3 Mon Sep 17 00:00:00 2001 From: email <15737449156@163.com> Date: Wed, 13 Aug 2025 21:20:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AA=E6=9C=89=E7=BB=98=E5=9B=BE=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E6=97=A0=E4=B8=B2=E5=8F=A3=E5=92=8Cmodbus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- untitled/hmidocument.cpp | 31 ++-- untitled/mainwindow.cpp | 20 --- untitled/mainwindow.h | 4 - untitled/modbusmanager.cpp | 0 untitled/modbusmanager.h | 4 - untitled/serialportmanager.cpp | 263 --------------------------------- untitled/serialportmanager.h | 57 ------- untitled/untitled.pro | 8 +- 8 files changed, 21 insertions(+), 366 deletions(-) delete mode 100644 untitled/modbusmanager.cpp delete mode 100644 untitled/modbusmanager.h delete mode 100644 untitled/serialportmanager.cpp delete mode 100644 untitled/serialportmanager.h diff --git a/untitled/hmidocument.cpp b/untitled/hmidocument.cpp index e91e52c..0e5fd07 100644 --- a/untitled/hmidocument.cpp +++ b/untitled/hmidocument.cpp @@ -21,7 +21,7 @@ #include #include #include - +#include HMIDocument::HMIDocument(QWidget *parent) : BaseDocument(HMI, parent), m_title("未命名HMI"), @@ -269,6 +269,7 @@ void HMIDocument::deleteSelectedItems() } // 显示属性对话框 +// 在HMIDocument::showItemProperties()方法中替换相关代码 void HMIDocument::showItemProperties() { QList selectedItems = m_scene->selectedItems(); @@ -283,10 +284,17 @@ void HMIDocument::showItemProperties() dialog.setWindowTitle("属性设置"); QFormLayout *form = new QFormLayout(&dialog); - // 名称输入 - 使用NamedItem接口 - QLineEdit *nameEdit = new QLineEdit(namedItem->name()); + // 线圈地址输入 - 使用SpinBox替代LineEdit + QSpinBox *coilAddrSpin = new QSpinBox(); + coilAddrSpin->setRange(0, 65535); // 设置PLC线圈地址常见范围 + // 尝试从名称解析现有地址(如果之前用数字作为名称) + bool isNumber; + int addr = namedItem->name().toInt(&isNumber); + if (isNumber) { + coilAddrSpin->setValue(addr); + } - // 颜色选择(根据图形类型) + // 颜色选择(保持不变) QColor tempColor1, tempColor2; QPushButton *colorBtn1 = new QPushButton; QPushButton *colorBtn2 = new QPushButton; @@ -303,11 +311,11 @@ void HMIDocument::showItemProperties() form->addRow("释放颜色:", colorBtn2); } - // 初始化颜色按钮 + // 初始化颜色按钮(保持不变) colorBtn1->setStyleSheet("background-color:" + tempColor1.name()); colorBtn2->setStyleSheet("background-color:" + tempColor2.name()); - // 颜色选择对话框 + // 颜色选择对话框(保持不变) connect(colorBtn1, &QPushButton::clicked, [&]() { QColor c = QColorDialog::getColor(tempColor1, &dialog); if (c.isValid()) { @@ -323,18 +331,18 @@ void HMIDocument::showItemProperties() } }); - // 布局组装 - form->addRow("对象:", nameEdit); + // 布局组装(将名称输入替换为线圈地址) + form->addRow("线圈地址:", coilAddrSpin); // 这里是关键修改 QDialogButtonBox *btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); form->addRow(btnBox); connect(btnBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(btnBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - // 应用属性 + // 应用属性(使用SpinBox的值作为地址) if (dialog.exec() == QDialog::Accepted) { setModified(true); - // 使用NamedItem接口设置名称 - namedItem->setName(nameEdit->text()); + // 将SpinBox的值转换为字符串保存到名称属性 + namedItem->setName(QString::number(coilAddrSpin->value())); if (auto ellipse = dynamic_cast(item)) { ellipse->setOnColor(tempColor1); @@ -346,7 +354,6 @@ void HMIDocument::showItemProperties() item->update(); } } - // 序列化图形项(用于复制粘贴) QByteArray HMIDocument::serializeItem(QGraphicsItem *item) { diff --git a/untitled/mainwindow.cpp b/untitled/mainwindow.cpp index 3988f3d..016f759 100644 --- a/untitled/mainwindow.cpp +++ b/untitled/mainwindow.cpp @@ -204,31 +204,11 @@ void MainWindow::createMenus() QMenu *simulationMenu = menuBar()->addMenu("仿真"); simulationMenu->setFont(itemFont); - // 连接动作 - QAction *connectAction = new QAction("连接设置", this); - connectAction->setFont(itemFont); - connect(connectAction, &QAction::triggered, this, &MainWindow::onConnectClicked); - simulationMenu->addAction(connectAction); - // 运行动作 (暂时留空) QAction *runAction = new QAction("运行", this); runAction->setFont(itemFont); runAction->setEnabled(false); simulationMenu->addAction(runAction); - -} -void MainWindow::onConnectClicked() -{ - if (!m_serialDialog) { - m_serialDialog = new SerialPortManager(this); - connect(m_serialDialog, &SerialPortManager::logMessage,this, &MainWindow::handleSerialLog); - } - - m_serialDialog->exec(); -} -void MainWindow::handleSerialLog(const QString &message) -{ - m_logEdit->append(message); } // 创建左侧工具栏 void MainWindow::createToolbars() diff --git a/untitled/mainwindow.h b/untitled/mainwindow.h index c0f591d..64422dc 100644 --- a/untitled/mainwindow.h +++ b/untitled/mainwindow.h @@ -7,7 +7,6 @@ #include #include #include "basedocument.h" -#include "serialportmanager.h" #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } @@ -34,10 +33,7 @@ private slots: void onCloseTab(int index); // 关闭标签页 void onClearLogButtonClicked(); void showLogContextMenu(const QPoint &pos); - void onConnectClicked(); // 连接菜单项槽函数 - void handleSerialLog(const QString &message); private: - SerialPortManager *m_serialDialog=nullptr; // 串口对话框 void createMenus(); // 创建菜单栏 QWidget* m_logPanelContainer; QDockWidget* m_logDock; diff --git a/untitled/modbusmanager.cpp b/untitled/modbusmanager.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/untitled/modbusmanager.h b/untitled/modbusmanager.h deleted file mode 100644 index c2e4bfc..0000000 --- a/untitled/modbusmanager.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef MODBUSMANAGER_H -#define MODBUSMANAGER_H - -#endif // MODBUSMANAGER_H diff --git a/untitled/serialportmanager.cpp b/untitled/serialportmanager.cpp deleted file mode 100644 index 0de7e1e..0000000 --- a/untitled/serialportmanager.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#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(); -} diff --git a/untitled/serialportmanager.h b/untitled/serialportmanager.h deleted file mode 100644 index 0f937e3..0000000 --- a/untitled/serialportmanager.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef SERIALPORTMANAGER_H -#define SERIALPORTMANAGER_H - -#include -#include -#include -#include -#include -#include -#include - -class SerialPortManager : public QDialog -{ - Q_OBJECT -public: - explicit SerialPortManager(QWidget *parent = nullptr); - ~SerialPortManager(); - - // 获取串口配置 - QString portName() const; - int baudRate() const; - QSerialPort::Parity parity() const; - QSerialPort::StopBits stopBits() const; - int stationAddress() const; - - // 新增串口操作接口 - bool isOpen() const; - void openSerialPort(); - void closeSerialPort(); - QByteArray readAll(); - void write(const QByteArray &data); - -signals: - void errorOccurred(const QString &error); - void logMessage(const QString &message); - -private slots: - void refreshPorts(); - void onConnectClicked(); - void handleReadyRead(); - void handleError(QSerialPort::SerialPortError error); - -private: - void populateBaudRates(); - void populateParities(); - void updateConnectionState(bool connected); - - QSerialPort *m_serial; // 串口对象 - QComboBox *m_portComboBox; - QComboBox *m_baudComboBox; - QComboBox *m_parityComboBox; - QSpinBox *m_stationSpinBox; - QPushButton *m_connectBtn; // 连接/断开按钮 - QLabel *m_statusLabel; // 状态标签 -}; - -#endif // SERIALPORTMANAGER_H diff --git a/untitled/untitled.pro b/untitled/untitled.pro index b670073..71ea9db 100644 --- a/untitled/untitled.pro +++ b/untitled/untitled.pro @@ -21,20 +21,16 @@ SOURCES += \ hmidocument.cpp \ main.cpp \ mainwindow.cpp \ - modbusmanager.cpp \ plcdocument.cpp \ - plcitems.cpp \ - serialportmanager.cpp + plcitems.cpp HEADERS += \ basedocument.h \ graphicsitems.h \ hmidocument.h \ mainwindow.h \ - modbusmanager.h \ plcdocument.h \ - plcitems.h \ - serialportmanager.h + plcitems.h FORMS += \ mainwindow.ui