@@ -1,6 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
<!DOCTYPE QtCreatorProject> | <!DOCTYPE QtCreatorProject> | ||||
<!-- Written by QtCreator 4.11.1, 2025-08-11T13:08:22. --> | |||||
<!-- Written by QtCreator 4.11.1, 2025-08-11T14:46:36. --> | |||||
<qtcreator> | <qtcreator> | ||||
<data> | <data> | ||||
<variable>EnvironmentId</variable> | <variable>EnvironmentId</variable> | ||||
@@ -444,7 +444,7 @@ void MainWindow::saveProject() | |||||
void MainWindow::connection() | void MainWindow::connection() | ||||
{ | { | ||||
modbusManager->connectToDevice("COM1",QSerialPort::BaudRate(9600),QSerialPort::DataBits(8),QSerialPort::EvenParity,QSerialPort::StopBits(1)); | modbusManager->connectToDevice("COM1",QSerialPort::BaudRate(9600),QSerialPort::DataBits(8),QSerialPort::EvenParity,QSerialPort::StopBits(1)); | ||||
modbusManager->startSimulation(2000); | |||||
modbusManager->startSimulation(1000); | |||||
} | } | ||||
void MainWindow::disconnection() | void MainWindow::disconnection() | ||||
@@ -65,26 +65,96 @@ void ModbusManager::stopSimulation() | |||||
pollTimer->stop(); | pollTimer->stop(); | ||||
} | } | ||||
//void ModbusManager::readRegisters() | |||||
//{ | |||||
// if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | |||||
// return; | |||||
// // 读取所有D寄存器 (保持寄存器) | |||||
// readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000); | |||||
// // 读取所有M寄存器 (线圈) | |||||
// readRegisterGroup(QModbusDataUnit::Coils, 0, 4000); | |||||
//} | |||||
//void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
//{ | |||||
// const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制 | |||||
// for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) { | |||||
// int readCount = qMin(MAX_REG_PER_REQUEST, count - addr); | |||||
// QModbusDataUnit unit(type, addr, readCount); | |||||
// if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | |||||
// QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | |||||
// pendingRequests[reply] = regType; | |||||
// connect(reply, &QModbusReply::finished, this, &ModbusManager::processModbusReply); | |||||
// } | |||||
// } | |||||
//} | |||||
void ModbusManager::readRegisters() | void ModbusManager::readRegisters() | ||||
{ | { | ||||
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | ||||
return; | return; | ||||
// 读取所有D寄存器 (保持寄存器) | |||||
readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000); | |||||
// 获取所有已注册的寄存器ID | |||||
QStringList regIds = registerManager->getAllRegisteredRegisters(); | |||||
QMap<QString, QSet<int>> regMap; // 按类型分组存储地址 | |||||
// 分组寄存器地址 | |||||
for (const QString &id : regIds) { | |||||
if (id.startsWith("D") || id.startsWith("M")) { | |||||
bool ok; | |||||
int addr = id.mid(1).toInt(&ok); | |||||
if (ok && addr >= 0 && addr <= 4000) { | |||||
regMap[id.left(1)].insert(addr); | |||||
} | |||||
} | |||||
} | |||||
// 读取D寄存器 (保持寄存器) | |||||
if (regMap.contains("D")) { | |||||
readRegisterGroup(QModbusDataUnit::HoldingRegisters, regMap["D"].values()); | |||||
} | |||||
// 读取所有M寄存器 (线圈) | |||||
readRegisterGroup(QModbusDataUnit::Coils, 0, 4000); | |||||
// 读取M寄存器 (线圈) | |||||
if (regMap.contains("M")) { | |||||
readRegisterGroup(QModbusDataUnit::Coils, regMap["M"].values()); | |||||
} | |||||
} | } | ||||
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses) | |||||
{ | { | ||||
const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制 | |||||
if (addresses.isEmpty()) return; | |||||
QList<int> sortedAddrs = addresses; | |||||
std::sort(sortedAddrs.begin(), sortedAddrs.end()); | |||||
// 合并连续地址范围 | |||||
int start = sortedAddrs.first(); | |||||
int end = start; | |||||
for (int i = 1; i < sortedAddrs.size(); i++) { | |||||
if (sortedAddrs[i] == end + 1) { | |||||
end = sortedAddrs[i]; | |||||
} else { | |||||
readAddressRange(type, start, end - start + 1); | |||||
start = sortedAddrs[i]; | |||||
end = start; | |||||
} | |||||
} | |||||
readAddressRange(type, start, end - start + 1); | |||||
} | |||||
for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) { | |||||
int readCount = qMin(MAX_REG_PER_REQUEST, count - addr); | |||||
void ModbusManager::readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
{ | |||||
const int MAX_REG_PER_REQUEST = 120; | |||||
QModbusDataUnit unit(type, addr, readCount); | |||||
for (int offset = 0; offset < count; offset += MAX_REG_PER_REQUEST) { | |||||
int readCount = qMin(MAX_REG_PER_REQUEST, count - offset); | |||||
QModbusDataUnit unit(type, startAddr + offset, readCount); | |||||
if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | ||||
QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | ||||
@@ -41,6 +41,8 @@ signals: | |||||
private slots: | private slots: | ||||
void readRegisters(); | void readRegisters(); | ||||
void processModbusReply(); | void processModbusReply(); | ||||
void readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses); | |||||
void readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count); | |||||
private: | private: | ||||
QModbusRtuSerialMaster *modbusDevice; | QModbusRtuSerialMaster *modbusDevice; | ||||
@@ -48,8 +50,6 @@ private: | |||||
QTimer* pollTimer; | QTimer* pollTimer; | ||||
int slaveAddress = 1; // 默认从站地址 | int slaveAddress = 1; // 默认从站地址 | ||||
QMap<QModbusReply*, QString> pendingRequests; | QMap<QModbusReply*, QString> pendingRequests; | ||||
void readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count); | |||||
}; | }; | ||||
#endif // MODBUSMANAGER_H | #endif // MODBUSMANAGER_H |
@@ -311,3 +311,28 @@ void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event) | |||||
} | } | ||||
QGraphicsView::mouseReleaseEvent(event); | QGraphicsView::mouseReleaseEvent(event); | ||||
} | } | ||||
void MyGraphicsView::wheelEvent(QWheelEvent *event) | |||||
{ | |||||
// 检查是否按下了 Ctrl 键 | |||||
if (event->modifiers() & Qt::ControlModifier) { | |||||
// 计算缩放因子 (每滚动一步缩放 10%) | |||||
const double zoomFactor = 1.1; | |||||
double scaleFactor = (event->angleDelta().y() > 0) ? zoomFactor : 1.0 / zoomFactor; | |||||
// 获取鼠标在场景中的位置 | |||||
QPointF scenePos = mapToScene(event->position().toPoint()); | |||||
// 执行缩放 | |||||
scale(scaleFactor, scaleFactor); | |||||
// 调整视图中心点,使缩放以鼠标位置为中心 | |||||
QPointF delta = scenePos - mapToScene(viewport()->rect().center()); | |||||
centerOn(scenePos - delta * (scaleFactor - 1)); | |||||
event->accept(); // 表示事件已处理 | |||||
} else { | |||||
// 没有按下 Ctrl 键,执行默认的滚动行为 | |||||
QGraphicsView::wheelEvent(event); | |||||
} | |||||
} |
@@ -16,8 +16,7 @@ class MyGraphicsView : public QGraphicsView | |||||
Q_OBJECT | Q_OBJECT | ||||
public: | public: | ||||
explicit MyGraphicsView(QWidget *parent = nullptr); | explicit MyGraphicsView(QWidget *parent = nullptr); | ||||
protected: | |||||
//protected: | |||||
void dragEnterEvent(QDragEnterEvent *event) override; | void dragEnterEvent(QDragEnterEvent *event) override; | ||||
void dragMoveEvent(QDragMoveEvent *event) override; | void dragMoveEvent(QDragMoveEvent *event) override; | ||||
void dropEvent(QDropEvent *event) override; | void dropEvent(QDropEvent *event) override; | ||||
@@ -27,6 +26,7 @@ protected: | |||||
void mousePressEvent(QMouseEvent *event) override; | void mousePressEvent(QMouseEvent *event) override; | ||||
void mouseMoveEvent(QMouseEvent *event) override; | void mouseMoveEvent(QMouseEvent *event) override; | ||||
void mouseReleaseEvent(QMouseEvent *event) override; | void mouseReleaseEvent(QMouseEvent *event) override; | ||||
void wheelEvent(QWheelEvent *event) override; | |||||
signals: | signals: | ||||
void itemBoundToRegister(Item*, QString); | void itemBoundToRegister(Item*, QString); | ||||