Compare commits
10 Commits
122999e6a7
...
b81eb7cb05
| Author | SHA1 | Date | |
|---|---|---|---|
| b81eb7cb05 | |||
| d11dcdd885 | |||
| 868b770e0e | |||
| 73243f8c7a | |||
| 55759defd7 | |||
| 9a7ebbca9f | |||
| bdd09484f4 | |||
| 96954c6527 | |||
| ba3f36db0c | |||
| d79d5c779e |
@@ -14,7 +14,7 @@
|
|||||||
#include <QModbusDataUnit>
|
#include <QModbusDataUnit>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
class ColoredSquare : public QWidget {
|
class ColoredSquare final : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ColoredSquare(QWidget *parent = nullptr);
|
explicit ColoredSquare(QWidget *parent = nullptr);
|
||||||
@@ -25,12 +25,12 @@ private:
|
|||||||
QColor m_color;
|
QColor m_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mainwindows : public QWidget {
|
class MainWindows final : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Mainwindows(QWidget *parent = nullptr);
|
explicit MainWindows(QWidget *parent = nullptr);
|
||||||
~Mainwindows() override;
|
~MainWindows() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onStateChanged(QModbusDevice::State state);
|
void onStateChanged(QModbusDevice::State state);
|
||||||
@@ -41,30 +41,36 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void createUIElements();
|
void createUIElements();
|
||||||
void initModbusConnection();
|
void initModbusConnection();
|
||||||
void writeRegister(int index);
|
|
||||||
void readRegisters();
|
void readRegisters();
|
||||||
void loadConfiguration();
|
void loadConfiguration();
|
||||||
|
void updateStatusBar() const; // Добавлен const
|
||||||
|
|
||||||
QTableWidget* m_table;
|
QTableWidget* m_table{};
|
||||||
QString m_ipAddress;
|
QString m_ipAddress;
|
||||||
int m_port;
|
int m_port{};
|
||||||
QVector<int> m_buttonRegisters;
|
QVector<int> m_buttonRegisters;
|
||||||
QVector<int> m_indicatorRegisters;
|
QVector<int> m_indicatorRegisters;
|
||||||
int m_buttonCount;
|
int m_buttonCount{};
|
||||||
int m_indicatorCount;
|
int m_indicatorCount{};
|
||||||
QVector<QPushButton*> m_buttons;
|
QVector<QPushButton*> m_buttons;
|
||||||
QVector<ColoredSquare*> m_squares;
|
QVector<ColoredSquare*> m_squares;
|
||||||
QVector<int> m_colorIndices;
|
QVector<int> m_colorIndices;
|
||||||
QVector<int> m_buttonValues; // Add this new member to store button states
|
QVector<int> m_buttonValues; // Add this new member to store button states
|
||||||
QVector<int> m_buttonBits; // Add this new member for button bits
|
QVector<int> m_buttonBits; // Add this new member for button bits
|
||||||
|
QVector<QString> m_buttonLabels;
|
||||||
|
QVector<QString> m_indicatorLabels;
|
||||||
|
|
||||||
QModbusTcpClient* m_modbusClient;
|
QModbusTcpClient* m_modbusClient;
|
||||||
QPushButton* m_connectButton;
|
QPushButton* m_connectButton{};
|
||||||
bool m_connected;
|
bool m_connected;
|
||||||
int m_responseTimeout;
|
int m_responseTimeout{};
|
||||||
int m_connectTimeout;
|
int m_connectTimeout{};
|
||||||
int m_pollInterval;
|
int m_pollInterval{};
|
||||||
QTimer* m_pollTimer;
|
QTimer* m_pollTimer{};
|
||||||
|
QLabel* m_statusLabel{};
|
||||||
|
int m_requestCounter;
|
||||||
|
int m_responseCounter;
|
||||||
|
bool m_disconnectRequested{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
qDebug() << QApplication::style();
|
qDebug() << QApplication::style();
|
||||||
|
|
||||||
auto *window = new Mainwindows();
|
auto *window = new MainWindows();
|
||||||
window->show();
|
window->show();
|
||||||
//window->init();
|
//window->init();
|
||||||
QApplication::exec();
|
QApplication::exec();
|
||||||
|
|||||||
@@ -5,13 +5,10 @@
|
|||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include "mainwindow.h"
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QModbusTcpClient>
|
|
||||||
#include <QModbusDataUnit>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
ColoredSquare::ColoredSquare(QWidget *parent) : QWidget(parent), m_color(Qt::gray) {
|
ColoredSquare::ColoredSquare(QWidget *parent) : QWidget(parent), m_color(Qt::gray) {
|
||||||
}
|
}
|
||||||
@@ -26,18 +23,29 @@ void ColoredSquare::paintEvent(QPaintEvent *) {
|
|||||||
painter.fillRect(rect(), m_color);
|
painter.fillRect(rect(), m_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mainwindows::Mainwindows(QWidget *parent)
|
MainWindows::MainWindows(QWidget *parent)
|
||||||
: QWidget(parent), m_modbusClient(nullptr), m_connected(false) {
|
: QWidget(parent), m_modbusClient(nullptr), m_connected(false),
|
||||||
|
m_requestCounter(0), m_responseCounter(0) {
|
||||||
|
|
||||||
|
// Устанавливаем кодировку для всего приложения
|
||||||
|
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
// Устанавливаем шрифт с поддержкой кириллицы
|
||||||
|
QFont font("Arial", 10); // или можно использовать "MS Shell Dlg 2"
|
||||||
|
this->setFont(font);
|
||||||
|
|
||||||
loadConfiguration();
|
loadConfiguration();
|
||||||
createUIElements();
|
createUIElements();
|
||||||
initModbusConnection();
|
initModbusConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::loadConfiguration() {
|
void MainWindows::loadConfiguration() {
|
||||||
const QString filePath = QCoreApplication::applicationDirPath() + "/config.ini";
|
const QString filePath = QCoreApplication::applicationDirPath() + "/config.ini";
|
||||||
QSettings settings(filePath, QSettings::IniFormat);
|
QSettings settings(filePath, QSettings::IniFormat);
|
||||||
|
|
||||||
|
// Устанавливаем кодировку для чтения файла конфигурации
|
||||||
|
settings.setIniCodec("UTF-8");
|
||||||
|
|
||||||
settings.beginGroup("Connection");
|
settings.beginGroup("Connection");
|
||||||
m_ipAddress = settings.value("ip", "127.0.0.1").toString();
|
m_ipAddress = settings.value("ip", "127.0.0.1").toString();
|
||||||
m_port = settings.value("port", 502).toInt();
|
m_port = settings.value("port", 502).toInt();
|
||||||
@@ -82,12 +90,32 @@ void Mainwindows::loadConfiguration() {
|
|||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
qDebug() << "Loaded" << m_buttonCount << "buttons and" << m_indicatorCount << "indicators";
|
// Load button labels
|
||||||
qDebug() << "Button registers:" << m_buttonRegisters;
|
settings.beginGroup("Registers");
|
||||||
qDebug() << "Indicator registers:" << m_indicatorRegisters;
|
for(int i = 1; i <= m_buttonCount; ++i) {
|
||||||
|
QString labelKey = QString("button_label%1").arg(i);
|
||||||
|
QString label = settings.value(labelKey).toString();
|
||||||
|
if(label.isEmpty()) {
|
||||||
|
label = QString("Button %1").arg(i);
|
||||||
|
}
|
||||||
|
m_buttonLabels.append(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load indicator labels
|
||||||
|
for(int i = 1; i <= m_indicatorCount; ++i) {
|
||||||
|
QString labelKey = QString("indicator_label%1").arg(i);
|
||||||
|
QString label = settings.value(labelKey).toString();
|
||||||
|
if(label.isEmpty()) {
|
||||||
|
label = QString("Indicator %1").arg(i);
|
||||||
|
}
|
||||||
|
m_indicatorLabels.append(label);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::initModbusConnection() {
|
void MainWindows::initModbusConnection() {
|
||||||
|
delete m_modbusClient;
|
||||||
|
|
||||||
m_modbusClient = new QModbusTcpClient(this);
|
m_modbusClient = new QModbusTcpClient(this);
|
||||||
|
|
||||||
// Set timeouts
|
// Set timeouts
|
||||||
@@ -96,63 +124,75 @@ void Mainwindows::initModbusConnection() {
|
|||||||
m_modbusClient->setTimeout(m_responseTimeout);
|
m_modbusClient->setTimeout(m_responseTimeout);
|
||||||
m_modbusClient->setNumberOfRetries(1);
|
m_modbusClient->setNumberOfRetries(1);
|
||||||
|
|
||||||
connect(m_modbusClient, &QModbusClient::stateChanged,
|
connect(m_modbusClient, &QModbusDevice::stateChanged,
|
||||||
this, &Mainwindows::onStateChanged);
|
this, &MainWindows::onStateChanged);
|
||||||
|
|
||||||
// Initialize poll timer
|
// Initialize poll timer
|
||||||
m_pollTimer = new QTimer(this);
|
if (!m_pollTimer) {
|
||||||
|
m_pollTimer = new QTimer(this);
|
||||||
|
}
|
||||||
m_pollTimer->setInterval(m_pollInterval);
|
m_pollTimer->setInterval(m_pollInterval);
|
||||||
connect(m_pollTimer, &QTimer::timeout, this, &Mainwindows::onPollTimer);
|
connect(m_pollTimer, &QTimer::timeout, this, &MainWindows::onPollTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::onStateChanged(QModbusDevice::State state) {
|
void MainWindows::onStateChanged(QModbusDevice::State state) {
|
||||||
if (state == QModbusDevice::ConnectedState) {
|
if (state == QModbusDevice::ConnectedState) {
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
m_connectButton->setText("Disconnect");
|
m_connectButton->setText("Disconnect");
|
||||||
|
m_requestCounter = 0;
|
||||||
|
m_responseCounter = 0;
|
||||||
|
updateStatusBar();
|
||||||
readRegisters();
|
readRegisters();
|
||||||
m_pollTimer->start(); // Start polling when connected
|
m_pollTimer->start(); // Start polling when connected
|
||||||
} else if (state == QModbusDevice::UnconnectedState) {
|
} else if (state == QModbusDevice::UnconnectedState) {
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
m_connectButton->setText("Connect");
|
m_connectButton->setText("Connect");
|
||||||
m_pollTimer->stop(); // Stop polling when disconnected
|
m_pollTimer->stop(); // Stop polling when disconnected
|
||||||
|
updateStatusBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::onConnectButtonClicked() {
|
void MainWindows::onConnectButtonClicked() {
|
||||||
if (!m_connected) {
|
if (!m_connected) {
|
||||||
|
m_disconnectRequested = false;
|
||||||
if (!m_modbusClient->connectDevice()) {
|
if (!m_modbusClient->connectDevice()) {
|
||||||
QMessageBox::critical(this, tr("Connection Error"),
|
QMessageBox::critical(this, tr("Connection Error"),
|
||||||
tr("Could not connect to the Modbus device!"));
|
tr("Could not connect to the Modbus device!"));
|
||||||
}
|
}
|
||||||
// Start connection timeout timer
|
// Start connection timeout timer
|
||||||
QTimer::singleShot(m_connectTimeout, this, [this]() {
|
QTimer::singleShot(m_connectTimeout, this, [this]() {
|
||||||
if (!m_connected) {
|
if (!m_connected && !m_disconnectRequested) {
|
||||||
m_modbusClient->disconnectDevice();
|
m_modbusClient->disconnectDevice();
|
||||||
QMessageBox::warning(this, tr("Connection Timeout"),
|
QMessageBox::warning(this, tr("Connection Timeout"),
|
||||||
tr("Connection attempt timed out!"));
|
tr("Connection attempt timed out!"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
m_disconnectRequested = true;
|
||||||
m_modbusClient->disconnectDevice();
|
m_modbusClient->disconnectDevice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::onPollTimer() {
|
void MainWindows::onPollTimer() {
|
||||||
if (m_connected) {
|
if (m_connected) {
|
||||||
readRegisters();
|
readRegisters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::readRegisters() {
|
void MainWindows::readRegisters() {
|
||||||
if (!m_connected) return;
|
if (!m_connected) return;
|
||||||
|
|
||||||
|
// Увеличиваем счетчик запросов
|
||||||
|
m_requestCounter += m_indicatorCount + m_buttonCount;
|
||||||
|
updateStatusBar();
|
||||||
|
|
||||||
// Read indicator registers
|
// Read indicator registers
|
||||||
for (int i = 0; i < m_indicatorCount; ++i) {
|
for (int i = 0; i < m_indicatorCount; ++i) {
|
||||||
if (i < m_indicatorRegisters.size()) {
|
if (i < m_indicatorRegisters.size()) {
|
||||||
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, m_indicatorRegisters[i], 1);
|
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, m_indicatorRegisters[i], 1);
|
||||||
if (auto *reply = m_modbusClient->sendReadRequest(readUnit, 1)) {
|
if (auto *reply = m_modbusClient->sendReadRequest(readUnit, 1)) {
|
||||||
if (!reply->isFinished()) {
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, this, &Mainwindows::onReadReady);
|
connect(reply, &QModbusReply::finished, this, &MainWindows::onReadReady);
|
||||||
} else {
|
} else {
|
||||||
delete reply;
|
delete reply;
|
||||||
}
|
}
|
||||||
@@ -166,7 +206,7 @@ void Mainwindows::readRegisters() {
|
|||||||
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, m_buttonRegisters[i], 1);
|
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, m_buttonRegisters[i], 1);
|
||||||
if (auto *reply = m_modbusClient->sendReadRequest(readUnit, 1)) {
|
if (auto *reply = m_modbusClient->sendReadRequest(readUnit, 1)) {
|
||||||
if (!reply->isFinished()) {
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, this, &Mainwindows::onReadReady);
|
connect(reply, &QModbusReply::finished, this, &MainWindows::onReadReady);
|
||||||
} else {
|
} else {
|
||||||
delete reply;
|
delete reply;
|
||||||
}
|
}
|
||||||
@@ -175,12 +215,16 @@ void Mainwindows::readRegisters() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::onReadReady() {
|
void MainWindows::onReadReady() {
|
||||||
auto reply = qobject_cast<QModbusReply *>(sender());
|
auto* reply = qobject_cast<QModbusReply*>(sender());
|
||||||
if (!reply) return;
|
if (!reply) return;
|
||||||
|
|
||||||
if (reply->error() == QModbusDevice::NoError) {
|
std::unique_ptr<QModbusReply> replyPtr(reply); // Автоматическое освобождение памяти
|
||||||
const QModbusDataUnit unit = reply->result();
|
|
||||||
|
if (replyPtr->error() == QModbusDevice::NoError) {
|
||||||
|
m_responseCounter++;
|
||||||
|
updateStatusBar();
|
||||||
|
const QModbusDataUnit unit = replyPtr->result();
|
||||||
int address = unit.startAddress();
|
int address = unit.startAddress();
|
||||||
int value = unit.value(0);
|
int value = unit.value(0);
|
||||||
|
|
||||||
@@ -188,8 +232,12 @@ void Mainwindows::onReadReady() {
|
|||||||
for (int i = 0; i < m_indicatorRegisters.size(); ++i) {
|
for (int i = 0; i < m_indicatorRegisters.size(); ++i) {
|
||||||
if (address == m_indicatorRegisters[i]) {
|
if (address == m_indicatorRegisters[i]) {
|
||||||
static const QColor colors[] = {Qt::gray, Qt::black, Qt::green};
|
static const QColor colors[] = {Qt::gray, Qt::black, Qt::green};
|
||||||
|
static const QString states[] = {"?", "Закрыт", "Открыт"};
|
||||||
m_colorIndices[i] = value % 3;
|
m_colorIndices[i] = value % 3;
|
||||||
m_squares[i]->setColor(colors[m_colorIndices[i]]);
|
m_squares[i]->setColor(colors[m_colorIndices[i]]);
|
||||||
|
if (auto* item = m_table->item(i, 3)) {
|
||||||
|
item->setText(states[m_colorIndices[i]]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,25 +247,39 @@ void Mainwindows::onReadReady() {
|
|||||||
if (address == m_buttonRegisters[i]) {
|
if (address == m_buttonRegisters[i]) {
|
||||||
m_buttonValues[i] = value;
|
m_buttonValues[i] = value;
|
||||||
bool bitState = (value >> m_buttonBits[i]) & 1;
|
bool bitState = (value >> m_buttonBits[i]) & 1;
|
||||||
m_buttons[i]->setText(QString("%1")
|
m_buttons[i]->setChecked(bitState); // Устанавливаем состояние кнопки
|
||||||
.arg(bitState ? "Закрыть" : "Открыть"));
|
bool hasIndicator = false;
|
||||||
|
// Проверяем, есть ли индикатор для этой кнопки
|
||||||
|
for (int j = 0; j < m_indicatorRegisters.size(); ++j) {
|
||||||
|
if (m_indicatorLabels[j].contains(m_buttonLabels[i], Qt::CaseInsensitive)) {
|
||||||
|
hasIndicator = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_buttons[i]->setText(hasIndicator ?
|
||||||
|
QString("%1").arg(bitState ? "Выкл" : "Вкл") :
|
||||||
|
QString("%1").arg(bitState ? "Закрыть" : "Открыть"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reply->deleteLater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mainwindows::createUIElements() {
|
void MainWindows::createUIElements() {
|
||||||
auto* mainLayout = new QVBoxLayout(this);
|
auto* mainLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
// Добавляем статусную строку
|
||||||
|
m_statusLabel = new QLabel(this);
|
||||||
|
m_statusLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||||||
|
updateStatusBar();
|
||||||
|
|
||||||
// Add connect button at the top
|
// Add connect button at the top
|
||||||
m_connectButton = new QPushButton("Connect", this);
|
m_connectButton = new QPushButton("Connect", this);
|
||||||
connect(m_connectButton, &QPushButton::clicked, this, &Mainwindows::onConnectButtonClicked);
|
connect(m_connectButton, &QPushButton::clicked, this, &MainWindows::onConnectButtonClicked);
|
||||||
mainLayout->addWidget(m_connectButton);
|
mainLayout->addWidget(m_connectButton);
|
||||||
|
|
||||||
// Create table with maximum of buttons or indicators
|
// Create table with maximum of buttons or indicators
|
||||||
int rowCount = qMax(m_buttonCount, m_indicatorCount);
|
int rowCount = qMax(m_buttonCount, m_indicatorCount);
|
||||||
m_table = new QTableWidget(rowCount, 2, this);
|
m_table = new QTableWidget(rowCount, 4, this); // Changed from 3 to 4 columns
|
||||||
|
|
||||||
// Setup table properties
|
// Setup table properties
|
||||||
m_table->verticalHeader()->setVisible(false);
|
m_table->verticalHeader()->setVisible(false);
|
||||||
@@ -226,48 +288,101 @@ void Mainwindows::createUIElements() {
|
|||||||
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
|
||||||
|
// Устанавливаем шрифт для таблицы
|
||||||
|
QFont tableFont("Arial", 10);
|
||||||
|
m_table->setFont(tableFont);
|
||||||
|
|
||||||
// Create UI elements
|
// Create UI elements
|
||||||
for(int i = 0; i < rowCount; ++i) {
|
for(int i = 0; i < rowCount; ++i) {
|
||||||
|
// Add label in first column
|
||||||
|
QString label;
|
||||||
if (i < m_buttonCount) {
|
if (i < m_buttonCount) {
|
||||||
|
label = m_buttonLabels[i];
|
||||||
|
} else if (i < m_indicatorCount) {
|
||||||
|
label = m_indicatorLabels[i];
|
||||||
|
}
|
||||||
|
m_table->setItem(i, 0, new QTableWidgetItem(label));
|
||||||
|
|
||||||
|
if (i < m_buttonCount) {
|
||||||
|
auto* container = new QWidget();
|
||||||
|
auto* containerLayout = new QHBoxLayout(container);
|
||||||
auto* button = new QPushButton(QString("Register %1 Bit %2").arg(m_buttonRegisters[i]).arg(m_buttonBits[i]), this);
|
auto* button = new QPushButton(QString("Register %1 Bit %2").arg(m_buttonRegisters[i]).arg(m_buttonBits[i]), this);
|
||||||
|
button->setFont(tableFont);
|
||||||
|
button->setCheckable(true);
|
||||||
|
button->setMaximumHeight(button->height() - 5);
|
||||||
|
containerLayout->addWidget(button);
|
||||||
|
containerLayout->setAlignment(Qt::AlignCenter);
|
||||||
|
containerLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_buttons.append(button);
|
m_buttons.append(button);
|
||||||
m_buttonValues.append(0);
|
m_buttonValues.append(0);
|
||||||
m_table->setCellWidget(i, 0, button);
|
m_table->setCellWidget(i, 1, container);
|
||||||
connect(button, &QPushButton::clicked, [this, i]() {
|
connect(button, &QPushButton::clicked, this, [this, i]() {
|
||||||
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, m_buttonRegisters[i], 1);
|
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, m_buttonRegisters[i], 1);
|
||||||
int currentValue = m_buttonValues[i];
|
int currentValue = m_buttonValues[i];
|
||||||
int newValue = currentValue ^ (1 << m_buttonBits[i]); // Toggle specific bit
|
int newValue = currentValue ^ (1 << m_buttonBits[i]);
|
||||||
m_buttonValues[i] = newValue;
|
m_buttonValues[i] = newValue;
|
||||||
writeUnit.setValue(0, newValue);
|
writeUnit.setValue(0, newValue);
|
||||||
if (auto *reply = m_modbusClient->sendWriteRequest(writeUnit, 1)) {
|
if (auto* reply = m_modbusClient->sendWriteRequest(writeUnit, 1)) {
|
||||||
if (!reply->isFinished())
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||||
else
|
} else {
|
||||||
delete reply;
|
delete reply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < m_indicatorCount) {
|
if (i < m_indicatorCount) {
|
||||||
auto* square = new ColoredSquare(this);
|
auto* container = new QWidget();
|
||||||
square->setFixedSize(m_table->rowHeight(i), m_table->rowHeight(i));
|
auto* containerLayout = new QHBoxLayout(container);
|
||||||
|
auto* square = new ColoredSquare(container);
|
||||||
|
square->setFixedSize(m_table->rowHeight(i) - 4, m_table->rowHeight(i) - 4); // Немного уменьшаем размер
|
||||||
|
containerLayout->addWidget(square);
|
||||||
|
containerLayout->setAlignment(Qt::AlignCenter);
|
||||||
|
containerLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_squares.append(square);
|
m_squares.append(square);
|
||||||
m_colorIndices.append(0);
|
m_colorIndices.append(0);
|
||||||
m_table->setCellWidget(i, 1, square);
|
m_table->setCellWidget(i, 2, container);
|
||||||
|
|
||||||
|
// Add status text cell
|
||||||
|
const auto statusItem = new QTableWidgetItem("?");
|
||||||
|
statusItem->setTextAlignment(Qt::AlignCenter);
|
||||||
|
m_table->setItem(i, 3, statusItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust column sizes
|
// Adjust column sizes
|
||||||
m_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
|
m_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||||
m_table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
|
m_table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||||
m_table->setColumnWidth(0, 100);
|
m_table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
|
||||||
m_table->setColumnWidth(1, 100);
|
m_table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
|
||||||
|
m_table->setColumnWidth(0, 180); // Label column
|
||||||
|
m_table->setColumnWidth(1, 100); // Button column
|
||||||
|
m_table->setColumnWidth(2, 50); // Square column
|
||||||
|
m_table->setColumnWidth(3, 100); // Status text column
|
||||||
|
|
||||||
mainLayout->addWidget(m_table);
|
mainLayout->addWidget(m_table);
|
||||||
|
mainLayout->addWidget(m_statusLabel);
|
||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// Обновляем расчет размера окна с учетом статусной строки
|
||||||
|
int totalWidth = m_table->horizontalHeader()->length() + 4;
|
||||||
|
int totalHeight = m_table->verticalHeader()->length() +
|
||||||
|
m_connectButton->height() +
|
||||||
|
m_statusLabel->sizeHint().height() + 20;
|
||||||
|
setFixedSize(totalWidth, totalHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mainwindows::~Mainwindows() {
|
void MainWindows::updateStatusBar() const {
|
||||||
|
QString status = QString("IP: %1 Port: %2 | Requests: %3 Responses: %4")
|
||||||
|
.arg(m_ipAddress)
|
||||||
|
.arg(m_port)
|
||||||
|
.arg(m_requestCounter)
|
||||||
|
.arg(m_responseCounter);
|
||||||
|
m_statusLabel->setText(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindows::~MainWindows() {
|
||||||
if (m_pollTimer) {
|
if (m_pollTimer) {
|
||||||
m_pollTimer->stop();
|
m_pollTimer->stop();
|
||||||
}
|
}
|
||||||
|
|||||||
19
config.ini
19
config.ini
@@ -6,15 +6,28 @@ connectTimeout=2000
|
|||||||
timeBetweenPolls=100
|
timeBetweenPolls=100
|
||||||
|
|
||||||
[Registers]
|
[Registers]
|
||||||
buttonCount=3
|
buttonCount=5
|
||||||
indicatorCount=4
|
indicatorCount=4
|
||||||
button_reg1=3
|
button_reg1=3
|
||||||
button_bit1=0
|
button_bit1=0
|
||||||
button_reg2=4
|
button_label1=valve 1
|
||||||
|
button_reg2=3
|
||||||
button_bit2=1
|
button_bit2=1
|
||||||
button_reg3=5
|
button_label2=Клапан 2
|
||||||
|
button_reg3=3
|
||||||
button_bit3=2
|
button_bit3=2
|
||||||
|
button_label3=Клапан 3
|
||||||
|
button_reg4=3
|
||||||
|
button_bit4=3
|
||||||
|
button_label4=Клапан 4
|
||||||
|
button_reg5=5
|
||||||
|
button_bit5=3
|
||||||
|
button_label5=Насос
|
||||||
indicator_reg1=13
|
indicator_reg1=13
|
||||||
|
indicator_label1=Статус клапана 1
|
||||||
indicator_reg2=14
|
indicator_reg2=14
|
||||||
|
indicator_label2=Статус клапана 2
|
||||||
indicator_reg3=15
|
indicator_reg3=15
|
||||||
|
indicator_label3=Статус клапана 3
|
||||||
indicator_reg4=16
|
indicator_reg4=16
|
||||||
|
indicator_label4=Статус насоса
|
||||||
|
|||||||
Reference in New Issue
Block a user