diff --git a/changevaluesdialog.cpp b/changevaluesdialog.cpp new file mode 100644 index 0000000..46f1d46 --- /dev/null +++ b/changevaluesdialog.cpp @@ -0,0 +1,47 @@ +#include "changevaluesdialog.h" +#include "ui_changevaluesdialog.h" + +// Qt includes +#include +#include + +ChangeValuesDialog::ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent) : + QDialog{parent}, + m_ui{std::make_unique()}, + m_modbus{modbus} +{ + m_ui->setupUi(this); + + qDebug() << "called"; + + m_ui->tableView->setModel(&m_model); + + m_ui->spinBoxFirstRegister->setValue(m_model.firstRegister()); + m_ui->spinBoxCount->setValue(m_model.count()); + + connect(m_ui->spinBoxFirstRegister, &QSpinBox::valueChanged, &m_model, &ChangeValuesModel::setFirstRegister); + connect(m_ui->spinBoxCount, &QSpinBox::valueChanged, &m_model, &ChangeValuesModel::setCount); + + connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &ChangeValuesDialog::sendRequest); + + + { + const auto addItem = [&](const auto &text, const auto &value){ + m_ui->comboBoxType->addItem(text, QVariant::fromValue(value)); + }; + addItem(tr("Discrete Inputs"), QModbusDataUnit::DiscreteInputs); + addItem(tr("Coils"), QModbusDataUnit::Coils); + addItem(tr("Input Registers"), QModbusDataUnit::InputRegisters); + addItem(tr("Holding Registers"), QModbusDataUnit::HoldingRegisters); + } +} + +ChangeValuesDialog::~ChangeValuesDialog() +{ + qDebug() << "called"; +} + +void ChangeValuesDialog::sendRequest() +{ + accept(); +} diff --git a/changevaluesdialog.h b/changevaluesdialog.h new file mode 100644 index 0000000..3366a86 --- /dev/null +++ b/changevaluesdialog.h @@ -0,0 +1,31 @@ +#pragma once + +// system includes +#include + +// Qt includes +#include + +// local includes +#include "changevaluesmodel.h" + +// forward declares +class QModbusTcpClient; +namespace Ui {class ChangeValuesDialog; } + +class ChangeValuesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent = nullptr); + ~ChangeValuesDialog() override; + +private slots: + void sendRequest(); + +private: + const std::unique_ptr m_ui; + QModbusTcpClient &m_modbus; + ChangeValuesModel m_model; +}; diff --git a/changevaluesdialog.ui b/changevaluesdialog.ui new file mode 100644 index 0000000..fc232d5 --- /dev/null +++ b/changevaluesdialog.ui @@ -0,0 +1,93 @@ + + + ChangeValuesDialog + + + + 0 + 0 + 400 + 300 + + + + Change values + + + + + + + + TextLabel + + + + + + + + + + First reister: + + + + + + + 9999 + + + + + + + Count: + + + + + + + 9999 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + rejected() + ChangeValuesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/changevaluesmodel.cpp b/changevaluesmodel.cpp new file mode 100644 index 0000000..fb961c3 --- /dev/null +++ b/changevaluesmodel.cpp @@ -0,0 +1,134 @@ +#include "changevaluesmodel.h" + +// Qt includes +#include + +ChangeValuesModel::ChangeValuesModel(QObject *parent) : + QAbstractTableModel{parent} +{ + m_registers.resize(m_count); + qDebug() << "size =" << m_registers.size(); +} + +ChangeValuesModel::~ChangeValuesModel() +{ + qDebug() << "called"; +} + +QModelIndex ChangeValuesModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_ASSERT(!parent.isValid()); + return createIndex(row, column); +} + +QModelIndex ChangeValuesModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return {}; +} + +int ChangeValuesModel::rowCount(const QModelIndex &parent) const +{ + Q_ASSERT(!parent.isValid()); + return m_count; +} + +int ChangeValuesModel::columnCount(const QModelIndex &parent) const +{ + Q_ASSERT(!parent.isValid()); + return 1; +} + +QVariant ChangeValuesModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(index.isValid()); + + switch (role) + { + case Qt::DisplayRole: + return QString::number(m_registers.at(m_firstRegister + index.row())); + case Qt::EditRole: + return m_registers.at(m_firstRegister + index.row()); + } + + return {}; +} + +QVariant ChangeValuesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch (orientation) + { + case Qt::Horizontal: + Q_ASSERT(section == 0); + + switch (role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch (section) + { + case 0: return tr("Value"); + } + __builtin_unreachable(); + break; + } + + break; + + case Qt::Vertical: + + switch (role) + { + case Qt::DisplayRole: return QString::number(m_firstRegister + section); + case Qt::EditRole: return m_firstRegister + section; + } + + default: + __builtin_unreachable(); + } + + return {}; +} + +Qt::ItemFlags ChangeValuesModel::flags(const QModelIndex &index) const +{ + return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; +} + +bool ChangeValuesModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + qDebug() << "setData" << index << value << Qt::ItemDataRole(role); + + if (!value.canConvert()) + { + qCritical() << "wrong type"; + return false; + } + + switch (role) + { + case Qt::EditRole: + m_registers[index.row() + m_firstRegister] = value.value(); + return true; + } + + return false; +} + +void ChangeValuesModel::setFirstRegister(uint16_t firstRegister) +{ + beginResetModel(); + m_firstRegister = firstRegister; + if (m_registers.size() < m_firstRegister + m_count) + m_registers.resize(m_firstRegister + m_count); + endResetModel(); +} + +void ChangeValuesModel::setCount(uint16_t count) +{ + beginResetModel(); + m_count = count; + if (m_registers.size() < m_firstRegister + m_count) + m_registers.resize(m_firstRegister + m_count); + endResetModel(); +} diff --git a/changevaluesmodel.h b/changevaluesmodel.h new file mode 100644 index 0000000..2d19333 --- /dev/null +++ b/changevaluesmodel.h @@ -0,0 +1,34 @@ +#pragma once + +// Qt includes +#include +#include + +class ChangeValuesModel : public QAbstractTableModel +{ +public: + explicit ChangeValuesModel(QObject *parent = nullptr); + ~ChangeValuesModel() override; + + uint16_t firstRegister() const { return m_firstRegister; } + uint16_t count() const { return m_count; } + + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &child) const override; + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + +public slots: + void setFirstRegister(uint16_t firstRegister); + void setCount(uint16_t count); + +private: + uint16_t m_firstRegister{}; + uint16_t m_count{100}; + + QVector m_registers; +}; diff --git a/mainwindow.cpp b/mainwindow.cpp index 1d74640..9864b95 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -12,6 +12,7 @@ // local includes #include "modbustablemodel.h" +#include "changevaluesdialog.h" // utilities namespace { @@ -60,6 +61,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_ui->pushButtonConnect, &QAbstractButton::pressed, this, &MainWindow::connectPressed); connect(m_ui->pushButtonRequest, &QAbstractButton::pressed, this, &MainWindow::requestPressed); + connect(m_ui->pushButtonWrite, &QAbstractButton::pressed, this, &MainWindow::writePressed); m_ui->tableView->setModel(m_model.get()); } @@ -156,6 +158,13 @@ void MainWindow::requestPressed() } } +void MainWindow::writePressed() +{ + ChangeValuesDialog dialog{*m_modbus, this}; + dialog.exec(); + qDebug() << "called"; +} + void MainWindow::modbusErrorOccured(int error) { const auto typedError = QModbusDevice::Error(error); diff --git a/mainwindow.h b/mainwindow.h index 923b370..8e21be2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -24,6 +24,7 @@ public: private slots: void connectPressed(); void requestPressed(); + void writePressed(); void modbusErrorOccured(int error); void modbusStateChanged(int state); diff --git a/mainwindow.ui b/mainwindow.ui index 035844e..8252d76 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -37,7 +37,7 @@ - 192.168.0.75 + 192.168.8.116 @@ -287,6 +287,26 @@ + + + + Write values + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/modbustablemodel.cpp b/modbustablemodel.cpp index 7b33503..8ea7b79 100644 --- a/modbustablemodel.cpp +++ b/modbustablemodel.cpp @@ -25,6 +25,7 @@ QModelIndex ModbusTableModel::index(int row, int column, const QModelIndex &pare QModelIndex ModbusTableModel::parent(const QModelIndex &child) const { + Q_UNUSED(child) return {}; } diff --git a/qtmodbustester.pro b/qtmodbustester.pro index 358456c..a901c7f 100644 --- a/qtmodbustester.pro +++ b/qtmodbustester.pro @@ -5,12 +5,17 @@ CONFIG += c++17 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 SOURCES += main.cpp \ + changevaluesdialog.cpp \ + changevaluesmodel.cpp \ mainwindow.cpp \ modbustablemodel.cpp FORMS += \ + changevaluesdialog.ui \ mainwindow.ui HEADERS += \ + changevaluesdialog.h \ + changevaluesmodel.h \ mainwindow.h \ modbustablemodel.h