@@ -1,6 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.11.1, 2025-08-11T14:46:36. --> | |||
<!-- Written by QtCreator 4.11.1, 2025-08-12T08:51:43. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
@@ -17,10 +17,12 @@ | |||
MainWindow::MainWindow(QWidget *parent) | |||
: QMainWindow(parent) | |||
, ui(new Ui::MainWindow) | |||
, registerManager(new RegisterManager(this)) | |||
, modbusManager(new ModbusManager(registerManager, this)) | |||
{ | |||
ui->setupUi(this); | |||
registerManager = new RegisterManager(this); | |||
modbusManager = new ModbusManager(registerManager, this); | |||
// registerManager = new RegisterManager(this); | |||
// modbusManager = new ModbusManager(registerManager, this); | |||
// 初始化PLC标签页 | |||
ui->plc_tab_widget->setTabsClosable(true); | |||
ui->plc_tab_widget->setMovable(true); | |||
@@ -60,9 +62,6 @@ MainWindow::MainWindow(QWidget *parent) | |||
// this, &PLC::updateConnectionStatus); | |||
// connect(modbusManager, &ModbusManager::errorOccurred, | |||
// this, &PLC::handleModbusError); | |||
// connect(this, &PLC::requestWriteRegister, | |||
// modbusManager, &ModbusManager::writeRegister); | |||
ui->stackedWidget->setCurrentIndex(0); | |||
setWindowTitle("未命名项目 - PLC编辑器"); | |||
@@ -207,6 +206,9 @@ void MainWindow::applyProjectToScene(const Project &proj, int pageIndex) | |||
connect(item, &Item::requestCopy, plcViews[pageIndex], &MyGraphicsView::onItemRequestCopy); | |||
connect(item, &Item::requestDelete, plcViews[pageIndex], &MyGraphicsView::onItemRequestDelete); | |||
connect(item, &Item::requestBindRegister, plcViews[pageIndex], &MyGraphicsView::onItemRequestBindRegister); | |||
connect(item, &Item::requestCompare, plcViews[pageIndex], &MyGraphicsView::onItemRequestCompare); | |||
connect(item, &Item::requestReset, plcViews[pageIndex], &MyGraphicsView::onItemRequestReset); | |||
connect(item, &Item::requestSetON,plcViews[pageIndex], &MyGraphicsView::onItemRequestSetON); | |||
plcScenes[pageIndex]->addItem(item); | |||
registerManager->bindItem(item,d.registerId); | |||
itemObjs.append(item); | |||
@@ -235,6 +237,9 @@ void MainWindow::applyProjectToScene(const Project &proj, int pageIndex) | |||
connect(item, &Item::requestCopy, hmiViews[pageIndex], &MyGraphicsView::onItemRequestCopy); | |||
connect(item, &Item::requestDelete, hmiViews[pageIndex], &MyGraphicsView::onItemRequestDelete); | |||
connect(item, &Item::requestBindRegister, hmiViews[pageIndex], &MyGraphicsView::onItemRequestBindRegister); | |||
connect(item, &Item::requestCompare, hmiViews[pageIndex], &MyGraphicsView::onItemRequestCompare); | |||
connect(item, &Item::requestReset, hmiViews[pageIndex], &MyGraphicsView::onItemRequestReset); | |||
connect(item, &Item::requestSetON,hmiViews[pageIndex], &MyGraphicsView::onItemRequestSetON); | |||
hmiScenes[pageIndex]->addItem(item); | |||
registerManager->bindItem(item,d.registerId); | |||
itemObjs.append(item); | |||
@@ -65,35 +65,6 @@ void ModbusManager::stopSimulation() | |||
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() | |||
{ | |||
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | |||
@@ -174,55 +174,125 @@ void MyGraphicsView::onItemRequestDelete(Item *item) | |||
delete item; | |||
} | |||
//void MyGraphicsView::onItemRequestBindRegister(Item *item) | |||
//{ | |||
// if (!item) return; | |||
// bool ok = false; | |||
// QString reg = QInputDialog::getText( | |||
// this, | |||
// "绑定寄存器", | |||
// "格式: <类型><地址>\n" | |||
// "类型: D(保持寄存器), M(线圈寄存器)\n" | |||
// "示例: D100, M200\n" | |||
// "地址范围: 0-4000", | |||
// QLineEdit::Normal, | |||
// item->registerId(), | |||
// &ok | |||
// ); | |||
// if (ok && !reg.isEmpty()) { | |||
// // 验证寄存器格式 | |||
// QRegularExpression regex("^[DMdm]\\d{1,4}$"); | |||
// QRegularExpressionMatch match = regex.match(reg); | |||
// if (!match.hasMatch()) { | |||
// QMessageBox::warning(this, "格式错误", "请输入有效的寄存器格式\n示例: D100, M200"); | |||
// return; | |||
// } | |||
// int address = reg.mid(1).toInt(); | |||
// if (address > 4000) { | |||
// QMessageBox::warning(this, "范围错误", "寄存器地址必须在0-4000范围内"); | |||
// return; | |||
// } | |||
// // 标准化格式 (D100) | |||
// QString newReg = QString("%1%2").arg(reg[0].toUpper()).arg(address); | |||
// if (item->setRegisterId(newReg)) | |||
// { | |||
// item->update(); | |||
// // 发出绑定信号 | |||
// emit itemBoundToRegister(item, newReg); | |||
// } | |||
// else | |||
// { | |||
// QMessageBox::warning(this, "提示", "请先重置再绑定新的寄存器"); | |||
// } | |||
// } | |||
//} | |||
void MyGraphicsView::onItemRequestBindRegister(Item *item) | |||
{ | |||
if (!item) return; | |||
bool ok = false; | |||
QString reg = QInputDialog::getText( | |||
this, | |||
"绑定寄存器", | |||
"格式: <类型><地址>\n" | |||
"类型: D(保持寄存器), M(线圈寄存器)\n" | |||
"示例: D100, M200\n" | |||
"地址范围: 0-4000", | |||
QLineEdit::Normal, | |||
item->registerId(), | |||
&ok | |||
); | |||
this, | |||
"绑定寄存器", | |||
"格式: <类型><地址>\n" | |||
"类型: D(保持寄存器), M(线圈寄存器), K(常数)\n" | |||
"示例: D100, M200, K100\n" | |||
"地址范围: 0-4000\n" | |||
"常数范围: 0-65535", | |||
QLineEdit::Normal, | |||
item->registerId(), | |||
&ok | |||
); | |||
if (ok && !reg.isEmpty()) { | |||
// 验证寄存器格式 | |||
QRegularExpression regex("^[DMdm]\\d{1,4}$"); | |||
// 验证输入格式 | |||
QRegularExpression regex("^([DMdm]\\d{1,4}|K\\d{1,5})$"); | |||
QRegularExpressionMatch match = regex.match(reg); | |||
if (!match.hasMatch()) { | |||
QMessageBox::warning(this, "格式错误", "请输入有效的寄存器格式\n示例: D100, M200"); | |||
QMessageBox::warning(this, "格式错误", "请输入有效的格式\n示例: D100, M200, K100"); | |||
return; | |||
} | |||
int address = reg.mid(1).toInt(); | |||
if (address > 4000) { | |||
QMessageBox::warning(this, "范围错误", "寄存器地址必须在0-4000范围内"); | |||
return; | |||
// 提取类型和值 | |||
QString type = reg.left(1).toUpper(); | |||
int value = reg.mid(1).toInt(); | |||
// 检查范围 | |||
if (type == "K") { | |||
if (value > 65535) { | |||
QMessageBox::warning(this, "范围错误", "常数必须在0-65535范围内"); | |||
return; | |||
} | |||
} else { | |||
if (value > 4000) { | |||
QMessageBox::warning(this, "范围错误", "寄存器地址必须在0-4000范围内"); | |||
return; | |||
} | |||
} | |||
// 标准化格式 (D100) | |||
QString newReg = QString("%1%2").arg(reg[0].toUpper()).arg(address); | |||
// 标准化格式 | |||
QString newReg = QString("%1%2").arg(type).arg(value); | |||
if (item->setRegisterId(newReg)) | |||
{ | |||
// 对于比较元件,直接设置值 | |||
if (item->itemType() == "比较" && type == "K") { | |||
// 常数直接设置值 | |||
item->setRegisterId(type); | |||
item->setRegisterValue(type, value); | |||
item->update(); | |||
// 发出绑定信号 | |||
emit itemBoundToRegister(item, newReg); | |||
} | |||
else | |||
{ | |||
QMessageBox::warning(this, "提示", "请先重置再绑定新的寄存器"); | |||
}else { | |||
// 寄存器绑定 | |||
if (type == "K") | |||
{ | |||
QMessageBox::warning(this, "提示", "此元件不能绑定常数"); | |||
} | |||
if (item->setRegisterId(newReg)) { | |||
item->update(); | |||
emit itemBoundToRegister(item, newReg); | |||
} else { | |||
QMessageBox::warning(this, "提示", "请先重置再绑定新的寄存器"); | |||
} | |||
} | |||
} | |||
} | |||
void MyGraphicsView::onItemRequestCompare(Item *item) | |||
{ | |||
if (!item) return; | |||