diff --git a/M3KTE_TERM.pro b/M3KTE_TERM/M3KTE_TERM.pro similarity index 70% rename from M3KTE_TERM.pro rename to M3KTE_TERM/M3KTE_TERM.pro index 83790e7..a51ffc2 100644 --- a/M3KTE_TERM.pro +++ b/M3KTE_TERM/M3KTE_TERM.pro @@ -1,4 +1,10 @@ QT += core gui +QT += widgets serialport +QT += serialbus widgets + +requires(qtConfig(combobox)) +QT += serialport +qtConfig(modbus-serialport): QT += serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -16,14 +22,22 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + devicesettingsdialog.cpp \ main.cpp \ - m3kte.cpp + m3kte.cpp \ + settingsdialog.cpp \ + writeregistermodel.cpp HEADERS += \ - m3kte.h + devicesettingsdialog.h \ + m3kte.h \ + settingsdialog.h \ + writeregistermodel.h FORMS += \ - m3kte.ui + devicesettingsdialog.ui \ + m3kte.ui \ + settingsdialog.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/M3KTE_TERM/devicesettingsdialog.cpp b/M3KTE_TERM/devicesettingsdialog.cpp new file mode 100644 index 0000000..0fc84a2 --- /dev/null +++ b/M3KTE_TERM/devicesettingsdialog.cpp @@ -0,0 +1,88 @@ +#include "devicesettingsdialog.h" +#include "ui_devicesettingsdialog.h" + +DeviceSettingsDialog::DeviceSettingsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::DeviceSettingsDialog) +{ + ui->setupUi(this); + + _currentBoardTimers[0] = ui->spinTimerBoard_1->value(); + _currentBoardTimers[1] = ui->spinTimerBoard_2->value(); + _currentBoardTimers[2] = ui->spinTimerBoard_3->value(); + _currentBoardTimers[3] = ui->spinTimerBoard_4->value(); + + _currentSpeed = ui->speedBox->currentText().toUInt(); + + _currentParity = ui->parityBox->currentIndex(); + + for(int i = 0; i < 4; i++) + { + _currentAdrs[i] = i+1; + } +} + +DeviceSettingsDialog::~DeviceSettingsDialog() +{ + delete ui; +} + +void DeviceSettingsDialog::on_buttonApplyChangeTimer_clicked() +{ + _currentBoardTimers[0] = ui->spinTimerBoard_1->value(); + _currentBoardTimers[1] = ui->spinTimerBoard_2->value(); + _currentBoardTimers[2] = ui->spinTimerBoard_3->value(); + _currentBoardTimers[3] = ui->spinTimerBoard_4->value(); +} + +void DeviceSettingsDialog::on_buttonApplyChangeSpeed_clicked() +{ + + _currentSpeed = ui->speedBox->currentText().toUInt(); + emit speedChanged(); +} + +void DeviceSettingsDialog::on_buttonApplyChangeParity_clicked() +{ + _currentParity = ui->parityBox->currentData().toUInt(); + emit parityChanged(); +} + +void DeviceSettingsDialog::on_buttonApplyChangeAdr_clicked() +{ + BoardIdHasBeenChanged* _boardIdHasBeenChanged = new BoardIdHasBeenChanged(ui->idComboBox->currentIndex(), ui->adrSpinBox->value()); + QCoreApplication::postEvent(parent(), _boardIdHasBeenChanged); +} + +unsigned DeviceSettingsDialog::currentBoardTimer(unsigned short _ID) +{ + return _currentBoardTimers[_ID]; +} + +unsigned DeviceSettingsDialog::currentSpeed() +{ + return _currentSpeed; +} + +unsigned short DeviceSettingsDialog::currentParity() +{ + return _currentParity; +} + +void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr) +{ + ui->speedBox->setCurrentText(QString::number(_currentSpeed=tmp_speed, 10)); + if(tmp_parity>0) + tmp_parity--; + ui->parityBox->setCurrentIndex(_currentParity = tmp_parity); + for(int i = 0; i < 4; i++) + { + _currentAdrs[i] = tmp_adr[i]; + } + on_idComboBox_currentIndexChanged(ui->idComboBox->currentIndex()); +} + +void DeviceSettingsDialog::on_idComboBox_currentIndexChanged(int index) +{ + ui->adrSpinBox->setValue(_currentAdrs[index]); +} diff --git a/M3KTE_TERM/devicesettingsdialog.h b/M3KTE_TERM/devicesettingsdialog.h new file mode 100644 index 0000000..78e85f1 --- /dev/null +++ b/M3KTE_TERM/devicesettingsdialog.h @@ -0,0 +1,66 @@ +#ifndef DEVICESETTINGSDIALOG_H +#define DEVICESETTINGSDIALOG_H + +#include +#include + +class BoardIdHasBeenChanged : public QEvent +{ +public: + BoardIdHasBeenChanged(const short num, const short newId) : QEvent(QEvent::User) {_BoardNum = num; _BoardNewID = newId;} + ~BoardIdHasBeenChanged() {} + + short BoardNum() const {return _BoardNum;} + short BoardNewID() const {return _BoardNewID;} + +private: + short _BoardNum; + short _BoardNewID; +}; + +namespace Ui { +class DeviceSettingsDialog; +} + +class DeviceSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DeviceSettingsDialog(QWidget *parent = nullptr); + ~DeviceSettingsDialog(); + + unsigned currentBoardTimer(unsigned short _ID); + unsigned currentSpeed(); + unsigned short currentParity(); + void updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr); +signals: + void parityChanged(); + void speedChanged(); + + void firstBoardAdrHasBeenChanged(); + void secondBoardAdrHasBeenChanged(); + void thirdBoardAdrHasBeenChanged(); + void fourthBoardAdrHasBeenChanged(); + +private slots: + void on_buttonApplyChangeTimer_clicked(); + + void on_buttonApplyChangeSpeed_clicked(); + + void on_buttonApplyChangeParity_clicked(); + + void on_buttonApplyChangeAdr_clicked(); + + void on_idComboBox_currentIndexChanged(int index); + +private: + unsigned _currentBoardTimers[4]; + unsigned _currentSpeed; + unsigned short _currentParity; + unsigned _currentAdrs[4]; + + Ui::DeviceSettingsDialog *ui; +}; + +#endif // DEVICESETTINGSDIALOG_H diff --git a/M3KTE_TERM/devicesettingsdialog.ui b/M3KTE_TERM/devicesettingsdialog.ui new file mode 100644 index 0000000..8b37b7f --- /dev/null +++ b/M3KTE_TERM/devicesettingsdialog.ui @@ -0,0 +1,324 @@ + + + DeviceSettingsDialog + + + + 0 + 0 + 243 + 431 + + + + Dialog + + + + + + Скорость обмена + + + + + + Применить + + + + + + + 5 + + + + 1200 + + + + + 2400 + + + + + 4800 + + + + + 9600 + + + + + 19200 + + + + + 31250 + + + + + 38400 + + + + + 57600 + + + + + 115200 + + + + + + + + + + + Период опроса плат + + + + + + Плата №3 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + мс + + + 1999999999 + + + 1000 + + + + + + + Плата №1 + + + + + + + Применить + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + мс + + + 1999999999 + + + 1000 + + + + + + + Плата №2 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + мс + + + 1 + + + 1999999999 + + + 1000 + + + + + + + Плата №4 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + мс + + + 1999999999 + + + 1000 + + + + + + + + + + Сетевой адрес МЗКТЭ + + + + + + Номер платы + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + + + + + + + Применить + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults + + + + + + + Контроль четности + + + + + + Применить + + + + + + + + No + + + + + Even + + + + + Odd + + + + + + + + + + + + + buttonBox + accepted() + DeviceSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DeviceSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/M3KTE_TERM/m3kte.cpp b/M3KTE_TERM/m3kte.cpp new file mode 100644 index 0000000..63325f9 --- /dev/null +++ b/M3KTE_TERM/m3kte.cpp @@ -0,0 +1,1254 @@ +#include "m3kte.h" +#include "ui_m3kte.h" + +#include "settingsdialog.h" +#include "writeregistermodel.h" + +#include +#include +#include +#include +#include + +//1024 768 +//Ширина колбы - уже +M3KTE::M3KTE(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::M3KTE) +{ + ui->setupUi(this); + + //Массив указателей на индикаторы напряжения топливных элементов + { + int i = 0; + m[i++] = ui->FuelCellVoltageBar_1; + m[i++] = ui->FuelCellVoltageBar_2; + m[i++] = ui->FuelCellVoltageBar_3; + m[i++] = ui->FuelCellVoltageBar_4; + m[i++] = ui->FuelCellVoltageBar_5; + m[i++] = ui->FuelCellVoltageBar_6; + m[i++] = ui->FuelCellVoltageBar_7; + m[i++] = ui->FuelCellVoltageBar_8; + m[i++] = ui->FuelCellVoltageBar_9; + m[i++] = ui->FuelCellVoltageBar_10; + m[i++] = ui->FuelCellVoltageBar_11; + m[i++] = ui->FuelCellVoltageBar_12; + m[i++] = ui->FuelCellVoltageBar_13; + m[i++] = ui->FuelCellVoltageBar_14; + m[i++] = ui->FuelCellVoltageBar_15; + m[i++] = ui->FuelCellVoltageBar_16; + m[i++] = ui->FuelCellVoltageBar_17; + m[i++] = ui->FuelCellVoltageBar_18; + m[i++] = ui->FuelCellVoltageBar_19; + m[i++] = ui->FuelCellVoltageBar_20; + m[i++] = ui->FuelCellVoltageBar_21; + m[i++] = ui->FuelCellVoltageBar_22; + m[i++] = ui->FuelCellVoltageBar_23; + m[i++] = ui->FuelCellVoltageBar_24; + m[i++] = ui->FuelCellVoltageBar_25; + m[i++] = ui->FuelCellVoltageBar_26; + m[i++] = ui->FuelCellVoltageBar_27; + m[i++] = ui->FuelCellVoltageBar_28; + m[i++] = ui->FuelCellVoltageBar_29; + m[i++] = ui->FuelCellVoltageBar_30; + m[i++] = ui->FuelCellVoltageBar_31; + m[i++] = ui->FuelCellVoltageBar_32; + m[i++] = ui->FuelCellVoltageBar_33; + m[i++] = ui->FuelCellVoltageBar_34; + m[i++] = ui->FuelCellVoltageBar_35; + m[i++] = ui->FuelCellVoltageBar_36; + m[i++] = ui->FuelCellVoltageBar_37; + m[i++] = ui->FuelCellVoltageBar_38; + m[i++] = ui->FuelCellVoltageBar_39; + m[i++] = ui->FuelCellVoltageBar_40; + m[i++] = ui->FuelCellVoltageBar_41; + m[i++] = ui->FuelCellVoltageBar_42; + m[i++] = ui->FuelCellVoltageBar_43; + m[i++] = ui->FuelCellVoltageBar_44; + m[i++] = ui->FuelCellVoltageBar_45; + m[i++] = ui->FuelCellVoltageBar_46; + m[i++] = ui->FuelCellVoltageBar_47; + m[i++] = ui->FuelCellVoltageBar_48; + m[i++] = ui->FuelCellVoltageBar_49; + m[i++] = ui->FuelCellVoltageBar_50; + m[i++] = ui->FuelCellVoltageBar_51; + m[i++] = ui->FuelCellVoltageBar_52; + m[i++] = ui->FuelCellVoltageBar_53; + m[i++] = ui->FuelCellVoltageBar_54; + m[i++] = ui->FuelCellVoltageBar_55; + m[i++] = ui->FuelCellVoltageBar_56; + m[i++] = ui->FuelCellVoltageBar_57; + m[i++] = ui->FuelCellVoltageBar_58; + m[i++] = ui->FuelCellVoltageBar_59; + m[i++] = ui->FuelCellVoltageBar_60; + m[i++] = ui->FuelCellVoltageBar_61; + m[i++] = ui->FuelCellVoltageBar_62; + m[i++] = ui->FuelCellVoltageBar_63; + m[i++] = ui->FuelCellVoltageBar_64; + m[i++] = ui->FuelCellVoltageBar_65; + m[i++] = ui->FuelCellVoltageBar_66; + m[i++] = ui->FuelCellVoltageBar_67; + m[i++] = ui->FuelCellVoltageBar_68; + m[i++] = ui->FuelCellVoltageBar_69; + m[i++] = ui->FuelCellVoltageBar_70; + m[i++] = ui->FuelCellVoltageBar_71; + m[i++] = ui->FuelCellVoltageBar_72; + m[i++] = ui->FuelCellVoltageBar_73; + m[i++] = ui->FuelCellVoltageBar_74; + m[i++] = ui->FuelCellVoltageBar_75; + m[i++] = ui->FuelCellVoltageBar_76; + m[i++] = ui->FuelCellVoltageBar_77; + m[i++] = ui->FuelCellVoltageBar_78; + m[i++] = ui->FuelCellVoltageBar_79; + m[i++] = ui->FuelCellVoltageBar_80; + m[i++] = ui->FuelCellVoltageBar_81; + m[i++] = ui->FuelCellVoltageBar_82; + m[i++] = ui->FuelCellVoltageBar_83; + m[i++] = ui->FuelCellVoltageBar_84; + m[i++] = ui->FuelCellVoltageBar_85; + m[i++] = ui->FuelCellVoltageBar_86; + m[i++] = ui->FuelCellVoltageBar_87; + m[i++] = ui->FuelCellVoltageBar_88; + m[i++] = ui->FuelCellVoltageBar_89; + m[i++] = ui->FuelCellVoltageBar_90; + m[i++] = ui->FuelCellVoltageBar_91; + m[i++] = ui->FuelCellVoltageBar_92; + m[i++] = ui->FuelCellVoltageBar_93; + m[i++] = ui->FuelCellVoltageBar_94; + m[i++] = ui->FuelCellVoltageBar_95; + m[i++] = ui->FuelCellVoltageBar_96; + m[i++] = ui->FuelCellVoltageBar_97; + m[i++] = ui->FuelCellVoltageBar_98; + m[i++] = ui->FuelCellVoltageBar_99; + m[i++] = ui->FuelCellVoltageBar_100; + m[i++] = ui->FuelCellVoltageBar_101; + m[i++] = ui->FuelCellVoltageBar_102; + m[i++] = ui->FuelCellVoltageBar_103; + m[i++] = ui->FuelCellVoltageBar_104; + m[i++] = ui->FuelCellVoltageBar_105; + m[i++] = ui->FuelCellVoltageBar_106; + m[i++] = ui->FuelCellVoltageBar_107; + m[i++] = ui->FuelCellVoltageBar_108; + m[i++] = ui->FuelCellVoltageBar_109; + m[i++] = ui->FuelCellVoltageBar_110; + m[i++] = ui->FuelCellVoltageBar_111; + m[i++] = ui->FuelCellVoltageBar_112; + m[i++] = ui->FuelCellVoltageBar_113; + m[i++] = ui->FuelCellVoltageBar_114; + m[i++] = ui->FuelCellVoltageBar_115; + m[i++] = ui->FuelCellVoltageBar_116; + m[i++] = ui->FuelCellVoltageBar_117; + m[i++] = ui->FuelCellVoltageBar_118; + m[i++] = ui->FuelCellVoltageBar_119; + m[i++] = ui->FuelCellVoltageBar_120; + m[i++] = ui->FuelCellVoltageBar_121; + m[i++] = ui->FuelCellVoltageBar_122; + m[i++] = ui->FuelCellVoltageBar_123; + m[i++] = ui->FuelCellVoltageBar_124; + m[i++] = ui->FuelCellVoltageBar_125; + m[i++] = ui->FuelCellVoltageBar_126; + m[i++] = ui->FuelCellVoltageBar_127; + m[i++] = ui->FuelCellVoltageBar_128; + m[i++] = ui->FuelCellVoltageBar_129; + m[i++] = ui->FuelCellVoltageBar_130; + m[i++] = ui->FuelCellVoltageBar_131; + m[i++] = ui->FuelCellVoltageBar_132; + m[i++] = ui->FuelCellVoltageBar_133; + m[i++] = ui->FuelCellVoltageBar_134; + m[i++] = ui->FuelCellVoltageBar_135; + m[i++] = ui->FuelCellVoltageBar_136; + m[i++] = ui->FuelCellVoltageBar_137; + m[i++] = ui->FuelCellVoltageBar_138; + m[i++] = ui->FuelCellVoltageBar_139; + m[i++] = ui->FuelCellVoltageBar_140; + m[i++] = ui->FuelCellVoltageBar_141; + m[i++] = ui->FuelCellVoltageBar_142; + m[i++] = ui->FuelCellVoltageBar_143; + m[i++] = ui->FuelCellVoltageBar_144; + m[i++] = ui->FuelCellVoltageBar_145; + m[i++] = ui->FuelCellVoltageBar_146; + m[i++] = ui->FuelCellVoltageBar_147; + m[i++] = ui->FuelCellVoltageBar_148; + m[i++] = ui->FuelCellVoltageBar_149; + m[i++] = ui->FuelCellVoltageBar_150; + m[i++] = ui->FuelCellVoltageBar_151; + m[i++] = ui->FuelCellVoltageBar_152; + m[i++] = ui->FuelCellVoltageBar_153; + m[i++] = ui->FuelCellVoltageBar_154; + m[i++] = ui->FuelCellVoltageBar_155; + m[i++] = ui->FuelCellVoltageBar_156; + m[i++] = ui->FuelCellVoltageBar_157; + m[i++] = ui->FuelCellVoltageBar_158; + m[i++] = ui->FuelCellVoltageBar_159; + m[i++] = ui->FuelCellVoltageBar_160; + m[i++] = ui->FuelCellVoltageBar_161; + m[i++] = ui->FuelCellVoltageBar_162; + m[i++] = ui->FuelCellVoltageBar_163; + m[i++] = ui->FuelCellVoltageBar_164; + m[i++] = ui->FuelCellVoltageBar_165; + m[i++] = ui->FuelCellVoltageBar_166; + m[i++] = ui->FuelCellVoltageBar_167; + m[i++] = ui->FuelCellVoltageBar_168; + m[i++] = ui->FuelCellVoltageBar_169; + m[i++] = ui->FuelCellVoltageBar_170; + m[i++] = ui->FuelCellVoltageBar_171; + m[i++] = ui->FuelCellVoltageBar_172; + m[i++] = ui->FuelCellVoltageBar_173; + m[i++] = ui->FuelCellVoltageBar_174; + m[i++] = ui->FuelCellVoltageBar_175; + m[i++] = ui->FuelCellVoltageBar_176; + m[i++] = ui->FuelCellVoltageBar_177; + m[i++] = ui->FuelCellVoltageBar_178; + m[i++] = ui->FuelCellVoltageBar_179; + m[i++] = ui->FuelCellVoltageBar_180; + m[i++] = ui->FuelCellVoltageBar_181; + m[i++] = ui->FuelCellVoltageBar_182; + m[i++] = ui->FuelCellVoltageBar_183; + m[i++] = ui->FuelCellVoltageBar_184; + m[i++] = ui->FuelCellVoltageBar_185; + m[i++] = ui->FuelCellVoltageBar_186; + m[i++] = ui->FuelCellVoltageBar_187; + m[i++] = ui->FuelCellVoltageBar_188; + m[i++] = ui->FuelCellVoltageBar_189; + m[i++] = ui->FuelCellVoltageBar_190; + m[i++] = ui->FuelCellVoltageBar_191; + m[i++] = ui->FuelCellVoltageBar_192; + m[i++] = ui->FuelCellVoltageBar_193; + m[i++] = ui->FuelCellVoltageBar_194; + m[i++] = ui->FuelCellVoltageBar_195; + m[i++] = ui->FuelCellVoltageBar_196; + m[i++] = ui->FuelCellVoltageBar_197; + m[i++] = ui->FuelCellVoltageBar_198; + m[i++] = ui->FuelCellVoltageBar_199; + m[i++] = ui->FuelCellVoltageBar_200; + m[i++] = ui->FuelCellVoltageBar_201; + m[i++] = ui->FuelCellVoltageBar_202; + m[i++] = ui->FuelCellVoltageBar_203; + m[i++] = ui->FuelCellVoltageBar_204; + m[i++] = ui->FuelCellVoltageBar_205; + m[i++] = ui->FuelCellVoltageBar_206; + m[i++] = ui->FuelCellVoltageBar_207; + m[i++] = ui->FuelCellVoltageBar_208; + m[i++] = ui->FuelCellVoltageBar_209; + m[i++] = ui->FuelCellVoltageBar_210; + m[i++] = ui->FuelCellVoltageBar_211; + m[i++] = ui->FuelCellVoltageBar_212; + m[i++] = ui->FuelCellVoltageBar_213; + m[i++] = ui->FuelCellVoltageBar_214; + m[i++] = ui->FuelCellVoltageBar_215; + m[i++] = ui->FuelCellVoltageBar_216; + m[i++] = ui->FuelCellVoltageBar_217; + m[i++] = ui->FuelCellVoltageBar_218; + m[i++] = ui->FuelCellVoltageBar_219; + m[i++] = ui->FuelCellVoltageBar_220; + m[i++] = ui->FuelCellVoltageBar_221; + m[i++] = ui->FuelCellVoltageBar_222; + m[i++] = ui->FuelCellVoltageBar_223; + m[i++] = ui->FuelCellVoltageBar_224; + m[i++] = ui->FuelCellVoltageBar_225; + m[i++] = ui->FuelCellVoltageBar_226; + m[i++] = ui->FuelCellVoltageBar_227; + m[i++] = ui->FuelCellVoltageBar_228; + m[i++] = ui->FuelCellVoltageBar_229; + m[i++] = ui->FuelCellVoltageBar_230; + m[i++] = ui->FuelCellVoltageBar_231; + m[i++] = ui->FuelCellVoltageBar_232; + m[i++] = ui->FuelCellVoltageBar_233; + m[i++] = ui->FuelCellVoltageBar_234; + m[i++] = ui->FuelCellVoltageBar_235; + m[i++] = ui->FuelCellVoltageBar_236; + m[i++] = ui->FuelCellVoltageBar_237; + m[i++] = ui->FuelCellVoltageBar_238; + m[i++] = ui->FuelCellVoltageBar_239; + m[i++] = ui->FuelCellVoltageBar_240; + m[i++] = ui->FuelCellVoltageBar_241; + m[i++] = ui->FuelCellVoltageBar_242; + m[i++] = ui->FuelCellVoltageBar_243; + m[i++] = ui->FuelCellVoltageBar_244; + m[i++] = ui->FuelCellVoltageBar_245; + m[i++] = ui->FuelCellVoltageBar_246; + m[i++] = ui->FuelCellVoltageBar_247; + m[i++] = ui->FuelCellVoltageBar_248; + m[i++] = ui->FuelCellVoltageBar_249; + m[i++] = ui->FuelCellVoltageBar_250; + m[i++] = ui->FuelCellVoltageBar_251; + m[i++] = ui->FuelCellVoltageBar_252; + m[i++] = ui->FuelCellVoltageBar_253; + m[i++] = ui->FuelCellVoltageBar_254; + m[i++] = ui->FuelCellVoltageBar_255; + m[i++] = ui->FuelCellVoltageBar_256; + m[i++] = ui->FuelCellVoltageBar_257; + m[i++] = ui->FuelCellVoltageBar_258; + m[i++] = ui->FuelCellVoltageBar_259; + m[i++] = ui->FuelCellVoltageBar_260; + m[i++] = ui->FuelCellVoltageBar_261; + m[i++] = ui->FuelCellVoltageBar_262; + m[i++] = ui->FuelCellVoltageBar_263; + m[i++] = ui->FuelCellVoltageBar_264; + m[i++] = ui->FuelCellVoltageBar_265; + m[i++] = ui->FuelCellVoltageBar_266; + m[i++] = ui->FuelCellVoltageBar_267; + m[i++] = ui->FuelCellVoltageBar_268; + m[i++] = ui->FuelCellVoltageBar_269; + m[i++] = ui->FuelCellVoltageBar_270; + m[i++] = ui->FuelCellVoltageBar_271; + m[i++] = ui->FuelCellVoltageBar_272; + m[i++] = ui->FuelCellVoltageBar_273; + m[i++] = ui->FuelCellVoltageBar_274; + m[i++] = ui->FuelCellVoltageBar_275; + m[i++] = ui->FuelCellVoltageBar_276; + m[i++] = ui->FuelCellVoltageBar_277; + m[i++] = ui->FuelCellVoltageBar_278; + m[i++] = ui->FuelCellVoltageBar_279; + m[i++] = ui->FuelCellVoltageBar_280; + m[i++] = ui->FuelCellVoltageBar_281; + m[i++] = ui->FuelCellVoltageBar_282; + m[i++] = ui->FuelCellVoltageBar_283; + m[i++] = ui->FuelCellVoltageBar_284; + m[i++] = ui->FuelCellVoltageBar_285; + m[i++] = ui->FuelCellVoltageBar_286; + m[i++] = ui->FuelCellVoltageBar_287; + m[i++] = ui->FuelCellVoltageBar_288; + m[i++] = ui->FuelCellVoltageBar_289; + m[i++] = ui->FuelCellVoltageBar_290; + m[i++] = ui->FuelCellVoltageBar_291; + m[i++] = ui->FuelCellVoltageBar_292; + m[i++] = ui->FuelCellVoltageBar_293; + m[i++] = ui->FuelCellVoltageBar_294; + m[i++] = ui->FuelCellVoltageBar_295; + m[i++] = ui->FuelCellVoltageBar_296; + m[i++] = ui->FuelCellVoltageBar_297; + m[i++] = ui->FuelCellVoltageBar_298; + m[i++] = ui->FuelCellVoltageBar_299; + m[i++] = ui->FuelCellVoltageBar_300; + m[i++] = ui->FuelCellVoltageBar_301; + m[i++] = ui->FuelCellVoltageBar_302; + m[i++] = ui->FuelCellVoltageBar_303; + m[i++] = ui->FuelCellVoltageBar_304; + m[i++] = ui->FuelCellVoltageBar_305; + m[i++] = ui->FuelCellVoltageBar_306; + m[i++] = ui->FuelCellVoltageBar_307; + m[i++] = ui->FuelCellVoltageBar_308; + m[i++] = ui->FuelCellVoltageBar_309; + m[i++] = ui->FuelCellVoltageBar_310; + m[i++] = ui->FuelCellVoltageBar_311; + m[i++] = ui->FuelCellVoltageBar_312; + m[i++] = ui->FuelCellVoltageBar_313; + m[i++] = ui->FuelCellVoltageBar_314; + m[i++] = ui->FuelCellVoltageBar_315; + m[i++] = ui->FuelCellVoltageBar_316; + m[i++] = ui->FuelCellVoltageBar_317; + m[i++] = ui->FuelCellVoltageBar_318; + m[i++] = ui->FuelCellVoltageBar_319; + m[i++] = ui->FuelCellVoltageBar_320; + } + /*QGroupBox *FCB[85]; + { + int i = 0; + FCB[i++] = ui->FuelCellBox_1; + FCB[i++] = ui->FuelCellBox_2; + FCB[i++] = ui->FuelCellBox_3; + FCB[i++] = ui->FuelCellBox_4; + FCB[i++] = ui->FuelCellBox_5; + FCB[i++] = ui->FuelCellBox_6; + FCB[i++] = ui->FuelCellBox_7; + FCB[i++] = ui->FuelCellBox_8; + FCB[i++] = ui->FuelCellBox_9; + FCB[i++] = ui->FuelCellBox_10; + FCB[i++] = ui->FuelCellBox_11; + FCB[i++] = ui->FuelCellBox_12; + FCB[i++] = ui->FuelCellBox_13; + FCB[i++] = ui->FuelCellBox_14; + FCB[i++] = ui->FuelCellBox_15; + FCB[i++] = ui->FuelCellBox_16; + FCB[i++] = ui->FuelCellBox_17; + FCB[i++] = ui->FuelCellBox_18; + FCB[i++] = ui->FuelCellBox_19; + FCB[i++] = ui->FuelCellBox_20; + FCB[i++] = ui->FuelCellBox_21; + FCB[i++] = ui->FuelCellBox_22; + FCB[i++] = ui->FuelCellBox_23; + FCB[i++] = ui->FuelCellBox_24; + FCB[i++] = ui->FuelCellBox_25; + FCB[i++] = ui->FuelCellBox_26; + FCB[i++] = ui->FuelCellBox_27; + FCB[i++] = ui->FuelCellBox_28; + FCB[i++] = ui->FuelCellBox_29; + FCB[i++] = ui->FuelCellBox_30; + FCB[i++] = ui->FuelCellBox_31; + FCB[i++] = ui->FuelCellBox_32; + FCB[i++] = ui->FuelCellBox_33; + FCB[i++] = ui->FuelCellBox_34; + FCB[i++] = ui->FuelCellBox_35; + FCB[i++] = ui->FuelCellBox_36; + FCB[i++] = ui->FuelCellBox_37; + FCB[i++] = ui->FuelCellBox_38; + FCB[i++] = ui->FuelCellBox_39; + FCB[i++] = ui->FuelCellBox_40; + FCB[i++] = ui->FuelCellBox_41; + FCB[i++] = ui->FuelCellBox_42; + FCB[i++] = ui->FuelCellBox_43; + FCB[i++] = ui->FuelCellBox_44; + FCB[i++] = ui->FuelCellBox_45; + FCB[i++] = ui->FuelCellBox_46; + FCB[i++] = ui->FuelCellBox_47; + FCB[i++] = ui->FuelCellBox_48; + FCB[i++] = ui->FuelCellBox_49; + FCB[i++] = ui->FuelCellBox_50; + FCB[i++] = ui->FuelCellBox_51; + FCB[i++] = ui->FuelCellBox_52; + FCB[i++] = ui->FuelCellBox_53; + FCB[i++] = ui->FuelCellBox_54; + FCB[i++] = ui->FuelCellBox_55; + FCB[i++] = ui->FuelCellBox_56; + FCB[i++] = ui->FuelCellBox_57; + FCB[i++] = ui->FuelCellBox_58; + FCB[i++] = ui->FuelCellBox_59; + FCB[i++] = ui->FuelCellBox_60; + FCB[i++] = ui->FuelCellBox_61; + FCB[i++] = ui->FuelCellBox_62; + FCB[i++] = ui->FuelCellBox_63; + FCB[i++] = ui->FuelCellBox_64; + FCB[i++] = ui->FuelCellBox_65; + FCB[i++] = ui->FuelCellBox_66; + FCB[i++] = ui->FuelCellBox_67; + FCB[i++] = ui->FuelCellBox_68; + FCB[i++] = ui->FuelCellBox_69; + FCB[i++] = ui->FuelCellBox_70; + FCB[i++] = ui->FuelCellBox_71; + FCB[i++] = ui->FuelCellBox_72; + FCB[i++] = ui->FuelCellBox_73; + FCB[i++] = ui->FuelCellBox_74; + FCB[i++] = ui->FuelCellBox_75; + FCB[i++] = ui->FuelCellBox_76; + FCB[i++] = ui->FuelCellBox_77; + FCB[i++] = ui->FuelCellBox_78; + FCB[i++] = ui->FuelCellBox_79; + FCB[i++] = ui->FuelCellBox_80; + FCB[i++] = ui->FuelCellBox_81; + FCB[i++] = ui->FuelCellBox_82; + FCB[i++] = ui->FuelCellBox_83; + FCB[i++] = ui->FuelCellBox_84; + FCB[i++] = ui->FuelCellBox_85; + }*/ + + m_settingsDialog = new SettingsDialog(this); + + ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils); + ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters); + ui->writeTable->addItem(tr("Accidents"), QModbusDataUnit::HoldingRegisters); + + for(int i = 0; i < 4; i++) + { + Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/3*20), false); + Boards[i].ModbusModelCoil->setStartAddress(0); + Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/3*20))); + Boards[i].ModbusModelHoldingReg = new WriteRegisterModel(this, (85 - (i/3*20))*2, true); + Boards[i].ModbusModelHoldingReg->setStartAddress(0); + Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/3*20))); + } + + m_deviceSettingsDialog = new DeviceSettingsDialog(this); + + modbusDevice = new QModbusRtuSerialMaster(this); + + Boards[0].boardScanners = new QTimer(); + Boards[1].boardScanners = new QTimer(); + Boards[2].boardScanners = new QTimer(); + Boards[3].boardScanners = new QTimer(); + + Boards[0].boardScanners->setSingleShot(true); + Boards[1].boardScanners->setSingleShot(true); + Boards[2].boardScanners->setSingleShot(true); + Boards[3].boardScanners->setSingleShot(true); + + connect(Boards[0].boardScanners, &QTimer::timeout, this, &M3KTE::firstBoardScan); + connect(Boards[1].boardScanners, &QTimer::timeout, this, &M3KTE::secondBoardScan); + connect(Boards[2].boardScanners, &QTimer::timeout, this, &M3KTE::thirdBoardScan); + connect(Boards[3].boardScanners, &QTimer::timeout, this, &M3KTE::fourthBoardScan); + + Boards[0].adr = 1; + Boards[1].adr = 2; + Boards[2].adr = 3; + Boards[3].adr = 4; + + initActions(); + + ui->BST_Off->setChecked(true); + + changeTable(ui->boardSelectBox->currentIndex(), ui->writeTable->currentIndex()); + + for(int i = 0; i<320; i++) + { + m[i]->setValue(3); + QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} "; + m[i]->setStyleSheet(style_fc_off); + } + //debug(); + + //Вызов окна настройки подключения + + //Вызов окна настройки устройства + +} + +M3KTE::~M3KTE() +{ + delete ui; +} + +void M3KTE::debug() +{ + srand(time(0)); + for(int i = 0; i < 320; i++) + { + m[i]->setTextVisible(true); + m[i]->setMinimumSize(25, 25); + m[i]->setMaximumSize(25, 25); + m[i]->resize(25, 25); + m[i]->setAlignment(Qt::AlignCenter); + m[i]->setFormat(QString("%1").arg((i%85))); + int j = rand()%4; + if(j!=3) j=rand()%4; + m[i]->setValue(j); + QString style_fc = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(j*50-50) + ", 255, 255, 100%);} "; + QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} "; + m[i]->setStyleSheet(style_fc); + + switch (j) { + case 1: + { + m[i]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(i/85+1), QString::number(i%85))); + break; + } + case 2: + { + m[i]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(i/85+1), QString::number(i%85))); + break; + } + case 3: + { + m[i]->setStatusTip(QString("П%1 ТЭ%2: Уровень напряжения в норме.").arg(QString::number(i/85+1), QString::number(i%85))); + break; + } + case 0: + m[i]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85))); + m[i]->setStyleSheet(style_fc_off); + m[i]->setValue(3); + break; + } + } +} + + +void M3KTE::initActions() +{ + ui->ConnectionMenuConnect->setEnabled(true); + ui->ConnectionMenuDisconnect->setEnabled(false); + ui->ConnectionMenuSettings->setEnabled(true); + + connect(ui->ConnectionMenuConnect, &QAction::triggered, + this, &M3KTE::onConnectClicked); + connect(ui->ConnectionMenuDisconnect, &QAction::triggered, + this, &M3KTE::onConnectClicked); + connect(ui->readButton, &QPushButton::clicked, + this, &M3KTE::onReadButtonClicked); + connect(ui->writeButton, &QPushButton::clicked, + this, &M3KTE::onWriteButtonClicked); + connect(ui->boardSelectBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &M3KTE::onSelectedBoardChanged); + connect(ui->writeTable, QOverload::of(&QComboBox::currentIndexChanged), + this, &M3KTE::onSelectedBoardChanged); + + connect(ui->ConnectionMenuSettings, &QAction::triggered, m_settingsDialog, &QDialog::show); + connect(ui->M3kteMenuSettings, &QAction::triggered, m_deviceSettingsDialog, &QDialog::show); +} + +void M3KTE::onConnectClicked() +{ + if (!modbusDevice) + return; + + statusBar()->clearMessage(); + if (modbusDevice->state() != QModbusDevice::ConnectedState) { + modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, + m_settingsDialog->settings().portName); +#if QT_CONFIG(modbus_serialport) + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, + m_settingsDialog->settings().parity); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, + m_settingsDialog->settings().baud); + modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, + m_settingsDialog->settings().dataBits); + modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, + m_settingsDialog->settings().stopBits); +#endif + modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); + modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries); + if (!modbusDevice->connectDevice()) { + statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000); + } else { + ui->ConnectionMenuConnect->setEnabled(false); + ui->ConnectionMenuDisconnect->setEnabled(true); + + ui->BST_Off->setChecked(false); + ui->BST_On->setChecked(true); + + ui->BSM_WorkInProgress->setChecked(true); + + if(pingNetworkDevices()) + { + unsigned tmp_adr[4]; + for (int i = 0; i < 4; i++) { + tmp_adr[i] = Boards[i].adr; + } + + m_deviceSettingsDialog->updateSettingsAfterConnection(m_settingsDialog->settings().baud, m_settingsDialog->settings().parity, tmp_adr); + } + //Опрос устройств + } + } else { + modbusDevice->disconnectDevice(); + ui->ConnectionMenuConnect->setEnabled(true); + ui->ConnectionMenuDisconnect->setEnabled(false); + ui->BST_Off->setChecked(true); + ui->BST_On->setChecked(false); + + ui->BSM_Warning->setChecked(false); + ui->BSM_Accident->setChecked(false); + ui->BSM_WorkInProgress->setChecked(false); + } +} + +void M3KTE::onReadButtonClicked() +{ + if (!modbusDevice) + return; + //ui->readValue->clear(); + statusBar()->clearMessage(); + + if (auto *reply = modbusDevice->sendReadRequest(readRequest(), Boards[ui->boardSelectBox->currentIndex()].adr)) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady); + else + delete reply; // broadcast replies return immediately + } else { + statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); + } +// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) { +// if (!reply->isFinished()) +// connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady); +// else +// delete reply; // broadcast replies return immediately +// } else { +// statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); +// } +// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) { +// if (!reply->isFinished()) +// connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady); +// else +// delete reply; // broadcast replies return immediately +// } else { +// statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); +// } +} + +void M3KTE::onReadReady() +{ + auto reply = qobject_cast(sender()); + if (!reply) + return; + + if (reply->error() == QModbusDevice::NoError) { + const QModbusDataUnit unit = reply->result(); + int Adr = 255; + for(int i = 0; i < 4; i++) + { + if(Boards[i].adr==reply->serverAddress()) + { + Adr = i; + break; + } + } + for (int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) { + //ui->readValue->addItem(entry); + if(unit.registerType() == QModbusDataUnit::Coils) + { + //QStandardItem *item = ui->writeValueTable->model()->item + if(unit.value(i)==1) + Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i, 2), Qt::Checked, Qt::CheckStateRole); + else + Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i, 2), Qt::Unchecked, Qt::CheckStateRole); + } + else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) + { + Boards[Adr].ModbusModelHoldingReg->setData(ui->writeValueTable->model()->index(i, 3), QString::number(unit.value(i), 16), Qt::EditRole); + } + } + } else if (reply->error() == QModbusDevice::ProtocolError) { + statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). + arg(reply->errorString()). + arg(reply->rawResult().exceptionCode(), -1, 16), 5000); + } else { + statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). + arg(reply->errorString()). + arg(reply->error(), -1, 16), 5000); + } + + reply->deleteLater(); +} + +void M3KTE::onWriteButtonClicked() +{ + if (!modbusDevice) + return; + statusBar()->clearMessage(); + + QModbusDataUnit writeUnit = writeRequest(); + QModbusDataUnit::RegisterType table = writeUnit.registerType(); + for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) { + if (table == QModbusDataUnit::Coils) + writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]); + else + writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i + writeUnit.startAddress()]); + } + + if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, ui->boardSelectBox->currentIndex()+1)) { + if (!reply->isFinished()) { + connect(reply, &QModbusReply::finished, this, [this, reply]() { + if (reply->error() == QModbusDevice::ProtocolError) { + statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)") + .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), + 5000); + } else if (reply->error() != QModbusDevice::NoError) { + statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)"). + arg(reply->errorString()).arg(reply->error(), -1, 16), 5000); + } + reply->deleteLater(); + }); + } else { + // broadcast replies return immediately + reply->deleteLater(); + } + } else { + statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000); + } +} + +void M3KTE::onSelectedBoardChanged(int index) +{ + changeTable(index, ui->writeTable->currentIndex()); +} + +void M3KTE::onWriteTableChanged(int index) +{ + changeTable(ui->boardSelectBox->currentIndex(), index); +} + +void M3KTE::changeTable(int board, int tabletype) +{ + + if(tabletype==0) + { + ui->writeValueTable->setModel(Boards[board].ModbusModelCoil); + int i = 0; + for(;irowCount();i++) + { + ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false); + } + ui->writeValueTable->hideColumn(3); + ui->writeValueTable->showColumn(2); + } + else + { + ui->writeValueTable->setModel(Boards[board].ModbusModelHoldingReg); + if(tabletype==1) + { + Boards[board].ModbusModelHoldingReg->setStartAddress(0); + int i = 0; + for (;irowCount()/2;i++) { + ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false); + } + for(;irowCount();i++) + { + ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true); + } + } + else + { + Boards[board].ModbusModelHoldingReg->setStartAddress(Boards[board].ModbusModelHoldingReg->rowCount()/2); + int i = 0; + for (;irowCount()/2;i++) { + ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true); + } + for(;irowCount();i++) + { + ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false); + } + } + ui->writeValueTable->hideColumn(2); + ui->writeValueTable->showColumn(3); + } +} + +QModbusDataUnit M3KTE::readRequest() const +{ + const auto table = + static_cast(ui->writeTable->currentData().toInt()); + + int startAddress = 85 * (ui->writeTable->currentIndex()/2); + Q_ASSERT(startAddress >= 0 && startAddress < 340); + + // do not go beyond 10 entries + quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress)); + return QModbusDataUnit(table, startAddress, numberOfEntries); +} + +QModbusDataUnit M3KTE::writeRequest() const +{ + const auto table = + static_cast(ui->writeTable->currentData().toInt()); + + int startAddress = 85 * (ui->writeTable->currentIndex()/2); + Q_ASSERT(startAddress >= 0 && startAddress < 340); + + // do not go beyond 10 entries + quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress)); + return QModbusDataUnit(table, startAddress, numberOfEntries); +} + +bool M3KTE::event(QEvent *event) +{ + if (event->type() == QEvent::User) + { + BoardIdHasBeenChanged* _event = static_cast(event); + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 172, 1); + _unit->setValue(0, _event->BoardNewID()); + modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardNum()].adr); + if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr)) + { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady); + else + delete reply; // broadcast replies return immediately + } else { + errorAdrChange(); + } + return true; + } + return QWidget::event(event); +} + +void M3KTE::checkAdrChange() +{ + auto reply = qobject_cast(sender()); + if (!reply) + { + errorAdrChange(); + return; + } + if (reply->error() == QModbusDevice::NoError) { + for (int i = 0; i < 4; i++) { + if(Boards[i]._tmp_adr == reply->serverAddress()) + { + //OK + Boards[i].adr = Boards[i]._tmp_adr; + reply->deleteLater(); + return; + } + } + //ERROR + errorAdrChange(); + reply->deleteLater(); + return; + } + errorAdrChange(); + reply->deleteLater(); +} + +void M3KTE::errorAdrChange() +{ + QMessageBox msgBox; + msgBox.setText("Не удалось изменить адрес устройства."); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + int ret = msgBox.exec(); +} + +void M3KTE::onSpeedUpdate() +{ + //Отсутствие контроля записи регистра на плате. + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1); + _unit->setValue(0, m_deviceSettingsDialog->currentSpeed()); + for (int i = 0; i < 4; i++) { + modbusDevice->sendWriteRequest(*_unit, Boards[i].adr); + } + + modbusDevice->disconnectDevice(); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, + m_settingsDialog->UpdateBaud(m_deviceSettingsDialog->currentSpeed())); + modbusDevice->connectDevice(); +} + +void M3KTE::onParityUpdate() +{ + //Отсутствие контроля записи регистра на плате. + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 174, 1); + switch (m_deviceSettingsDialog->currentParity()) + { + case 0: //Нет контроля + { + _unit->setValue(0, 0x000); + break; + } + case 1: //Четный + { + _unit->setValue(0, 0x0400); + break; + } + case 2: //Нечетный + { + _unit->setValue(0, 0x0800); + break; + } + } + for (int i = 0; i < 4; i++) { + modbusDevice->sendWriteRequest(*_unit, Boards[i].adr); + } + + modbusDevice->disconnectDevice(); + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, + m_settingsDialog->UpdateParity(m_deviceSettingsDialog->currentParity())); + modbusDevice->connectDevice(); +} + +bool M3KTE::pingNetworkDevices() +{ + int i=0; + QTimer *timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &M3KTE::timeForPingIsGone); + timer->setSingleShot(true); + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); + int tmp_adr = 0; + + auto bar = new QProgressDialog(this); + bar->setLabelText(tr("Поиск плат...")); + bar->setCancelButton(nullptr); + bar->setRange(0, 4); + bar->setMinimumDuration(100); + bar->setValue(i); + + + for(i=0; i<4;) + { + bar->setValue(i+1); + timerForPingSignal = false; + timer->start(m_settingsDialog->settings().responseTime); + auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr); + while(!reply->isFinished() && !timerForPingSignal) + { + QCoreApplication::processEvents(); + } + if(timerForPingSignal) + {} + else + { + timer->stop(); + Boards[i].adr = Boards[i]._tmp_adr = tmp_adr; + i++; + } + tmp_adr++; + if(tmp_adr>=247) + { + //ERROR + //OUT OF RANGE + QMessageBox::warning(this, "Ошибка при сканировании сети.", QString("Выход за пределы допустимых адресов. Найдено %1 плат").arg(i)); + bar->deleteLater(); + onConnectClicked(); + return false; + } + } + bar->setLabelText(tr("Сканирование регистров...")); + bar->setValue(0); + bar->setRange(0, 12); + QModbusDataUnit* _unit_settings[3]; + _unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85); + _unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85); + _unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85); + + for(i=0; i<4; i++) + { + for (int j = 0; j<3; j++) + { + bar->setValue(i*3+j+2); + timerForPingSignal = false; + timer->start(m_settingsDialog->settings().responseTime); + auto *reply = modbusDevice->sendReadRequest(*_unit_settings[j], Boards[i].adr); + while(!reply->isFinished() && !timerForPingSignal) + { + QCoreApplication::processEvents(); + } + if(timerForPingSignal) + { + QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Таймаут при опросе устройства %1 по адресу %2").arg(i).arg(Boards[i].adr)); + onConnectClicked(); + return false; + } + else + { + timer->stop(); + stepForScanCurrentSettings(reply); + } + } + } + beginScanBoards(); + bar->deleteLater(); + return true; + +} + +void M3KTE::timeForPingIsGone() +{ + timerForPingSignal=true; +} + +void M3KTE::beginScanBoards() +{ + firstBoardScan(); + secondBoardScan(); + thirdBoardScan(); + fourthBoardScan(); + return; +} + +void M3KTE::firstBoardScan() +{ + if (!modbusDevice) + return; + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); + statusBar()->clearMessage(); + + if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[0].adr)) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::firstBoardReady); + else + delete reply; // broadcast replies return immediately + } else { + QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(1), QString(tr("Read error: ") + modbusDevice->errorString())); + statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); + } +} + +void M3KTE::secondBoardScan() +{ + if (!modbusDevice) + return; + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); + statusBar()->clearMessage(); + + if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[1].adr)) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::secondBoardReady); + else + delete reply; // broadcast replies return immediately + } else { + QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(2), QString(tr("Read error: ") + modbusDevice->errorString())); + statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); + } +} + +void M3KTE::thirdBoardScan() +{ + if (!modbusDevice) + return; + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); + statusBar()->clearMessage(); + + if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[2].adr)) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::thirdBoardReady); + else + delete reply; // broadcast replies return immediately + } else { + QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(3), QString(tr("Read error: ") + modbusDevice->errorString())); + statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); + } +} + +void M3KTE::fourthBoardScan() +{ + if (!modbusDevice) + return; + + QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); + statusBar()->clearMessage(); + + if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[3].adr)) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &M3KTE::fourthBoardReady); + else + delete reply; // broadcast replies return immediately + } else { + QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(4), QString(tr("Read error: ") + modbusDevice->errorString())); + statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); + } + +} + +void M3KTE::firstBoardReady() +{ + auto reply = qobject_cast(sender()); + displayResultOfScan(reply, 0); + reply->deleteLater(); + Boards[0].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(0)); +} + +void M3KTE::secondBoardReady() +{ + auto reply = qobject_cast(sender()); + displayResultOfScan(reply, 1); + reply->deleteLater(); + Boards[1].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(1)); +} + +void M3KTE::thirdBoardReady() +{ + auto reply = qobject_cast(sender()); + displayResultOfScan(reply, 2); + reply->deleteLater(); + Boards[2].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(2)); +} + +void M3KTE::fourthBoardReady() +{ + auto reply = qobject_cast(sender()); + displayResultOfScan(reply, 3); + reply->deleteLater(); + Boards[3].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(3)); +} + +void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID) +{ + if (!reply) + return; + + if (reply->error() == QModbusDevice::NoError) { + + const QModbusDataUnit unit = reply->result(); + bool W_Flag = false; + bool A_Flag = false; + if(unit.startAddress() != 0 || unit.valueCount() != 85) + { + //ERROR + reply->deleteLater(); + QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID), QString("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount())); + return; + } + + for(int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) + { + if(Boards[boardID].ModbusModelCoil->data(Boards[boardID].ModbusModelCoil->index(i, 2)).Int) + { + int j = 0; + if(Boards[boardID].ModbusModelHoldingReg->data(Boards[boardID].ModbusModelHoldingReg->index(85+i, 3)).Int > unit.value(i)) + { + j = 1; + m[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); + A_Flag = true; + } + else if(Boards[boardID].ModbusModelHoldingReg->data(Boards[boardID].ModbusModelHoldingReg->index(i, 3)).Int > unit.value(i)) + { + j = 2; + m[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); + W_Flag = true; + } + else + { + j = 3; + m[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Уровень напряжения в норме.").arg(QString::number(boardID+1), QString::number(i%85))); + } + m[i+boardID*85]->setValue(j); + QString style_fc = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(j*50-50) + ", 255, 255, 100%);} "; + m[i+boardID*85]->setStyleSheet(style_fc); + } + else + { + m[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(boardID+1), QString::number(i%85))); + QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} "; + m[i+boardID*85]->setStyleSheet(style_fc_off); + } + } + if(A_Flag) + statusM3KTE.Accidents[boardID] = true; + if(W_Flag) + statusM3KTE.Warnings[boardID] = true; + + + ui->BSM_Warning->setEnabled(false); + ui->BSM_Accident->setEnabled(false); + ui->BSM_WorkInProgress->setEnabled(true); + for(int i = 0; i < 4; i++) + { + if(statusM3KTE.Accidents[i]) + { + ui->BSM_WorkInProgress->setEnabled(false); + ui->BSM_Warning->setEnabled(false); + ui->BSM_Accident->setEnabled(true); + break; + } + if(statusM3KTE.Warnings[i]) + { + ui->BSM_WorkInProgress->setEnabled(false); + ui->BSM_Accident->setEnabled(false); + ui->BSM_Warning->setEnabled(true); + } + } + } + reply->deleteLater(); +} + +void M3KTE::stepForScanCurrentSettings(QModbusReply *reply) +{ + if (reply->error() == QModbusDevice::NoError) { + const QModbusDataUnit unit = reply->result(); + int Adr = 255; + for(int i = 0; i < 4; i++) + { + if(Boards[i].adr==reply->serverAddress()) + { + Adr = i; + break; + } + } + for (int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) { + //ui->readValue->addItem(entry); + if(unit.registerType() == QModbusDataUnit::Coils) + { + //QStandardItem *item = ui->writeValueTable->model()->item + if(unit.value(i)==1) + Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i, 2), Qt::Checked, Qt::CheckStateRole); + else + Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i, 2), Qt::Unchecked, Qt::CheckStateRole); + } + else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) + { + Boards[Adr].ModbusModelHoldingReg->setData(ui->writeValueTable->model()->index(i, 3), QString::number(unit.value(i), 16), Qt::EditRole); + } + } + } else if (reply->error() == QModbusDevice::ProtocolError) { + statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). + arg(reply->errorString()). + arg(reply->rawResult().exceptionCode(), -1, 16), 5000); + } else { + statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). + arg(reply->errorString()). + arg(reply->error(), -1, 16), 5000); + } + + reply->deleteLater(); +} diff --git a/M3KTE_TERM/m3kte.h b/M3KTE_TERM/m3kte.h new file mode 100644 index 0000000..2fc1048 --- /dev/null +++ b/M3KTE_TERM/m3kte.h @@ -0,0 +1,107 @@ +#ifndef M3KTE_H +#define M3KTE_H + +#include +#include +#include + +#include +#include "writeregistermodel.h" +#include "devicesettingsdialog.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#if QT_CONFIG(modbus_serialport) +#include +#endif + +QT_BEGIN_NAMESPACE +namespace Ui { class M3KTE; class SettingsDialog;} +QT_END_NAMESPACE + +class SettingsDialog; +class WriteRegisterModel; + +class M3KTE : public QMainWindow +{ + Q_OBJECT +private: + void initActions(); + QModbusDataUnit readRequest() const; + QModbusDataUnit writeRequest() const; + void changeTable(int board, int tabletype); + void debug(); + void errorAdrChange(); + bool event(QEvent* event); + bool pingNetworkDevices(); + void beginScanBoards(); + void displayResultOfScan(QModbusReply *reply, int boardID); + void stepForScanCurrentSettings(QModbusReply *reply); +private slots: + void onConnectClicked(); + + void onReadButtonClicked(); + void onReadReady(); + + void timeForPingIsGone(); + + void checkAdrChange(); + + void onWriteButtonClicked(); + void onSelectedBoardChanged(int index); + void onWriteTableChanged(int index); + + void onSpeedUpdate(); + void onParityUpdate(); + + + void firstBoardScan(); + void secondBoardScan(); + void thirdBoardScan(); + void fourthBoardScan(); + + void firstBoardReady(); + void secondBoardReady(); + void thirdBoardReady(); + void fourthBoardReady(); +public: + M3KTE(QWidget *parent = nullptr); + ~M3KTE(); + +private: + bool timerForPingSignal = false; + + + + Ui::M3KTE *ui; + //int DeviceOnNetwork[4]; + QProgressBar *m[320]; + QModbusReply *lastRequest = nullptr; + QModbusClient *modbusDevice = nullptr; + DeviceSettingsDialog *m_deviceSettingsDialog = nullptr; + SettingsDialog *m_settingsDialog = nullptr; + //WriteRegisterModel *writeModel = nullptr; + + struct StatusM3KTE{ + bool Warnings[4]; + bool Accidents[4]; + }statusM3KTE; + + struct BoardModbusRegisters + { + int adr; + int _tmp_adr; + WriteRegisterModel *ModbusModelCoil; + WriteRegisterModel *ModbusModelHoldingReg; + QTimer *boardScanners; + }Boards[4]; +}; +#endif // M3KTE_H diff --git a/M3KTE_TERM/m3kte.ui b/M3KTE_TERM/m3kte.ui new file mode 100644 index 0000000..f7fed7e --- /dev/null +++ b/M3KTE_TERM/m3kte.ui @@ -0,0 +1,14377 @@ + + + M3KTE + + + + 0 + 0 + 956 + 598 + + + + + 0 + 0 + + + + M3KTE + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + + + 10 + + + 10 + + + 10 + + + 6 + + + + + Плата №4 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + Плата №3 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + Плата №2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + Плата №1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 3 + + + 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::Vertical + + + false + + + QProgressBar::TopToBottom + + + + + + + + + + + + + + + + 0 + 0 + + + + Статус Терминала + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + Отключено + + + + + + + Подключено + + + + + + + + + + Статус МЗКТЕ + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + Работа + + + + + + + Предупреждение + + + + + + + false + + + Авария + + + + + + + + + + + + + 0 + 25 + + + + Записать + + + + + + + + Плата №1 + + + + + Плата №2 + + + + + Плата №3 + + + + + Плата №4 + + + + + + + + + + + + 0 + 25 + + + + Считать + + + + + + + + + + + + + + 0 + 0 + 956 + 20 + + + + + Подключение + + + + + + + + + МЗКТЕ + + + + + + + + + + Настройки + + + + + Настройки + + + + + Подключить + + + + + Отключить + + + + + + diff --git a/main.cpp b/M3KTE_TERM/main.cpp similarity index 100% rename from main.cpp rename to M3KTE_TERM/main.cpp diff --git a/M3KTE_TERM/settingsdialog.cpp b/M3KTE_TERM/settingsdialog.cpp new file mode 100644 index 0000000..48e4a1f --- /dev/null +++ b/M3KTE_TERM/settingsdialog.cpp @@ -0,0 +1,62 @@ +#include "settingsdialog.h" +#include "ui_settingsdialog.h" + +SettingsDialog::SettingsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SettingsDialog) +{ + ui->setupUi(this); + + ui->parityCombo->setCurrentIndex(1); +#if QT_CONFIG(modbus_serialport) + ui->baudCombo->setCurrentText(QString::number(m_settings.baud)); + ui->dataBitsCombo->setCurrentText(QString::number(m_settings.dataBits)); + ui->stopBitsCombo->setCurrentText(QString::number(m_settings.stopBits)); +#endif + ui->timeoutSpinner->setValue(m_settings.responseTime); + ui->retriesSpinner->setValue(m_settings.numberOfRetries); + + connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() { +#if QT_CONFIG(modbus_serialport) + m_settings.portName = ui->portEdit->text(); + m_settings.parity = ui->parityCombo->currentIndex(); + if (m_settings.parity > 0) + m_settings.parity++; + m_settings.baud = ui->baudCombo->currentText().toInt(); + m_settings.dataBits = ui->dataBitsCombo->currentText().toInt(); + m_settings.stopBits = ui->stopBitsCombo->currentText().toInt(); +#endif + m_settings.responseTime = ui->timeoutSpinner->value(); + m_settings.numberOfRetries = ui->retriesSpinner->value(); + + hide(); + }); +} + +SettingsDialog::~SettingsDialog() +{ + delete ui; +} + +SettingsDialog::Settings SettingsDialog::settings() const +{ + return m_settings; +} + +int SettingsDialog::UpdateBaud(int baud) +{ + ui->baudCombo->setCurrentText(QString::number(baud, 10)); + return (m_settings.baud = baud); +} + +int SettingsDialog::UpdateParity(int parity) +{ + ui->parityCombo->setCurrentIndex(parity); + if(parity>0) + { + return (m_settings.parity = ++parity); + } + else { + return (m_settings.parity = parity); + } +} diff --git a/M3KTE_TERM/settingsdialog.h b/M3KTE_TERM/settingsdialog.h new file mode 100644 index 0000000..6b576ca --- /dev/null +++ b/M3KTE_TERM/settingsdialog.h @@ -0,0 +1,44 @@ +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include +#include +#include +#if QT_CONFIG(modbus_serialport) +#include +#endif + +namespace Ui { +class SettingsDialog; +} + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +public: + struct Settings { + QString portName; + int parity = QSerialPort::NoParity; + int baud = 31250; + int dataBits = QSerialPort::Data8; + int stopBits = QSerialPort::OneStop; + int responseTime = 1000; + int numberOfRetries = 3; + }; + + explicit SettingsDialog(QWidget *parent = nullptr); + ~SettingsDialog(); + + Settings settings() const; + + int UpdateBaud(int baud); + int UpdateParity(int parity); + + +private: + Settings m_settings; + Ui::SettingsDialog *ui; +}; + +#endif // SETTINGSDIALOG_H diff --git a/M3KTE_TERM/settingsdialog.ui b/M3KTE_TERM/settingsdialog.ui new file mode 100644 index 0000000..e4d2e1a --- /dev/null +++ b/M3KTE_TERM/settingsdialog.ui @@ -0,0 +1,284 @@ + + + SettingsDialog + + + + 0 + 0 + 311 + 288 + + + + Dialog + + + + + + мс + + + -1 + + + 5000 + + + 20 + + + 200 + + + + + + + 3 + + + + + + + Тайм-аут ответа: + + + + + + + Qt::Vertical + + + + 20 + 127 + + + + + + + + Serial Parameters + + + + + + Порт + + + + + + + + + + Чётность + + + + + + + + No + + + + + Even + + + + + Odd + + + + + + + + Скорость + + + + + + + 5 + + + + 1200 + + + + + 2400 + + + + + 4800 + + + + + 9600 + + + + + 19200 + + + + + 31250 + + + + + 38400 + + + + + 57600 + + + + + 115200 + + + + + + + + Биты данных + + + + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + + Стоп-биты + + + + + + + + 1 + + + + + 3 + + + + + 2 + + + + + + + + + + + Количество повторов: + + + + + + + + 0 + 25 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + AcceptOrRejectButtonBox + accepted() + SettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + AcceptOrRejectButtonBox + rejected() + SettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/M3KTE_TERM/writeregistermodel.cpp b/M3KTE_TERM/writeregistermodel.cpp new file mode 100644 index 0000000..eabcde7 --- /dev/null +++ b/M3KTE_TERM/writeregistermodel.cpp @@ -0,0 +1,125 @@ +#include "writeregistermodel.h" + +#include "writeregistermodel.h" + +enum { NumColumn = 0, NameColumn = 1, CoilsColumn = 2, HoldingColumn = 3, ColumnCount = 4}; + +WriteRegisterModel::WriteRegisterModel(QObject *parent, int _tmpRC, bool _isHR) + : QAbstractTableModel(parent), + m_coils(RowCount=_tmpRC, false), m_holdingRegisters(RowCount=_tmpRC, 0u) +{ + isHR=_isHR; +} + +int WriteRegisterModel::rowCount(const QModelIndex &/*parent*/) const +{ + return RowCount; +} + +int WriteRegisterModel::columnCount(const QModelIndex &/*parent*/) const +{ + return ColumnCount; +} + +QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return QVariant(); + + Q_ASSERT(m_coils.count() == RowCount); + Q_ASSERT(m_holdingRegisters.count() == RowCount); + + if (index.column() == NumColumn && role == Qt::DisplayRole) + return QString::number(index.row()); + + if (index.column() == NameColumn && role == Qt::DisplayRole) + return QString("ТЭ%1").arg(index.row()%(RowCount/(1+isHR))); + + if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils + return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked; + + if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers + return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16)); + + return QVariant(); + +} + +QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case NumColumn: + return QStringLiteral("#Reg"); + case NameColumn: + return QStringLiteral("Fuel Cell"); + case CoilsColumn: + return QStringLiteral("Coils"); + case HoldingColumn: + return QStringLiteral("Holding Registers"); + default: + break; + } + } + return QVariant(); +} + +bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return false; + + Q_ASSERT(m_coils.count() == RowCount); + Q_ASSERT(m_holdingRegisters.count() == RowCount); + + if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils + auto s = static_cast(value.toUInt()); + s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row()); + emit dataChanged(index, index); + return true; + } + + if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers + bool result = false; + quint16 newValue = value.toString().toUShort(&result, 16); + if (result) + m_holdingRegisters[index.row()] = newValue; + + emit dataChanged(index, index); + return result; + } + + return false; +} + +Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return QAbstractTableModel::flags(index); + + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + if ((index.row() < m_address) || (index.row() >= (m_address + m_number))) + flags &= ~Qt::ItemIsEnabled; + + if (index.column() == CoilsColumn) // coils + return flags | Qt::ItemIsUserCheckable; + if (index.column() == HoldingColumn) // holding registers + return flags | Qt::ItemIsEditable; + + return flags; +} + +void WriteRegisterModel::setStartAddress(int address) +{ + m_address = address; + //emit updateViewport(); +} + +void WriteRegisterModel::setNumberOfValues(const QString &number) +{ + m_number = number.toInt(); + //emit updateViewport(); +} diff --git a/M3KTE_TERM/writeregistermodel.h b/M3KTE_TERM/writeregistermodel.h new file mode 100644 index 0000000..9637aa2 --- /dev/null +++ b/M3KTE_TERM/writeregistermodel.h @@ -0,0 +1,38 @@ +#ifndef WRITEREGISTERMODEL_H +#define WRITEREGISTERMODEL_H + +#include +#include +#include + +class WriteRegisterModel : public QAbstractTableModel +{ +private: + bool isHR; + int RowCount; +public: + WriteRegisterModel(QObject *parent = nullptr, int _tmpRC = 85, bool _isHR = false); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +public slots: + void setStartAddress(int address); + void setNumberOfValues(const QString &number); + +signals: + void updateViewport(); + +public: + int m_number = 0; + int m_address = 0; + QBitArray m_coils; + QVector m_holdingRegisters; +}; +#endif // WRITEREGISTERMODEL_H diff --git a/m3kte.cpp b/m3kte.cpp deleted file mode 100644 index 9146c24..0000000 --- a/m3kte.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "m3kte.h" -#include "ui_m3kte.h" - -M3KTE::M3KTE(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::M3KTE) -{ - ui->setupUi(this); -} - -M3KTE::~M3KTE() -{ - delete ui; -} - diff --git a/m3kte.h b/m3kte.h deleted file mode 100644 index de4199c..0000000 --- a/m3kte.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef M3KTE_H -#define M3KTE_H - -#include - -QT_BEGIN_NAMESPACE -namespace Ui { class M3KTE; } -QT_END_NAMESPACE - -class M3KTE : public QMainWindow -{ - Q_OBJECT - -public: - M3KTE(QWidget *parent = nullptr); - ~M3KTE(); - -private: - Ui::M3KTE *ui; -}; -#endif // M3KTE_H diff --git a/m3kte.ui b/m3kte.ui deleted file mode 100644 index 1f1464c..0000000 --- a/m3kte.ui +++ /dev/null @@ -1,22 +0,0 @@ - - - M3KTE - - - - 0 - 0 - 800 - 600 - - - - M3KTE - - - - - - - - diff --git a/ТЗ/modbus_data.h b/ТЗ/modbus_data.h new file mode 100644 index 0000000..f8d4ae8 --- /dev/null +++ b/ТЗ/modbus_data.h @@ -0,0 +1,373 @@ +/** + ************************************************************************** + * @file modbus_data.h + * @brief Заголовочный файл с описанием даты MODBUS. + * @details Данный файл необходимо подключается в rs_message.h. После rs_message.h + * подключается к основному проекту. + * + * @defgroup MODBUS_DATA + * @ingroup MODBUS + * @brief Modbus data description + * + *************************************************************************/ +#include "stdint.h" +//--------------DEFINES FOR REGISTERS--------------- +// DEFINES FOR ARRAYS +/** + * @addtogroup MODBUS_DATA_RERISTERS_DEFINES + * @ingroup MODBUS_DATA + * @brief Defines for registers + Структура дефайна адресов + @verbatim + Для массивов регистров: + R__ADDR - модбас адресс первого регистра в массиве + R__QNT - количество регистров в массиве + + @endverbatim + * @{ + */ + + +/** + * @brief Скорость обмена + */ +typedef enum //MB_SpeedTypeDef +{ + MB_9600bs = 0x0000, ///< Скорость 9600 б/с + MB_14400bs = 0x0001, ///< Скорость 14400 б/с + MB_19200bs = 0x0002, ///< Скорость 19200 б/с + MB_31250bs = 0x0003, ///< Скорость 31250 б/с + MB_38400bs = 0x0004, ///< Скорость 38400 б/с + MB_56000bs = 0x0005, ///< Скорость 56000 б/с + MB_57600bs = 0x0006, ///< Скорость 57600 б/с + MB_115200bs = 0x0007, ///< Скорость 115200 б/с + mb16bit = 0x1000, ///< костыль чтобы enum был 16-битный... или забить на enum, пока не определился +}MB_SpeedTypeDef; + +/** + * @brief Контроль четности + */ +typedef enum //MB_ParityCtrlTypeDef +{ + NoParityCtrl = 0x0000, ///< контроля нет + EvenParityCtrl = 0x0400, ///< четный контроль + OddParityCtrl = 0x0600, ///< нечетый контроль +}MB_ParityCtrlTypeDef; + + +/** + * @brief Регистры хранения для уставок параметров МКЗТЭ + */ +typedef struct //MB_DataHoldRegsTypeDef +{ + + uint16_t Warning_Setpoints[85]; /*!< @brief Адреса 0-84: Уставки «Предупреждение» + @details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Предупреждение». + + Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */ + + uint16_t Errors_Setpoints[85]; /*!< @brief Адреса 85-169: Уставки «Авария» + @details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Авария». + + Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */ + + uint16_t Commands_Mode; /*!< @brief Адрес 170: Уставка «Команды» + @details Принимаемые значения: + - 0x0000 – стандартная работа + - 0x0001 – запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются) */ + + uint16_t reserved; ///< Адрес 171 зарезервирован + + uint16_t MZKTE_Network_Adress; /*!< @brief Адрес 172: Уставка «Сетевой адрес МЗКТЭ» + @details При удачной записи этого регистра ответный фрейм не отправляется */ + + MB_SpeedTypeDef Modbus_Speed:16; /*!< @brief Адрес 173: Уставка «Скорость обмена» + @details Принимаемые значения описаны в @ref MB_SpeedTypeDef. + + При удачной записи этого регистра ответный фрейм не отправляется */ + + MB_ParityCtrlTypeDef Parity_Control:16; /*!< @brief Адрес 174: Уставка «Команды» + @details Принимаемые значения описаны в @ref MB_ParityCtrlTypeDef. + + При удачной записи этого регистра ответный фрейм не отправляется */ +}MB_DataHoldRegsTypeDef; + + + +/** + * @brief Номер неисправности МЗКТЭ + */ +typedef enum //MB_MZKTEErrorsTypeDef +{ + No_Err = 0x00, ///< Неисправность отсутствует + Err_Digit_5V_Power = 0x01, ///< Неисправность цифрового источника питания +5 В + Err_Analog_15V_5V_3V_Power = 0x02, ///< Неисправность аналогового источника питания (±15 В/+5 В/+3,3 В) + Err_SCI_5V_Power = 0x03, ///< Неисправность источника питания последовательных интерфейсов микроконтроллера +5 В + Err_24V_Power = 0x04, ///< Неисправность источника питания +24 В + Program_Err_1 = 0x05, ///< Программная ошибка 1 + Program_Err_2 = 0x06, ///< Программная ошибка 2 + Program_Err_3 = 0x07, ///< Программная ошибка 3 + Program_Err_4 = 0x08, ///< Программная ошибка 4 + Program_Err_5 = 0x09, ///< Программная ошибка 5 + Program_Err_6 = 0x0A, ///< Программная ошибка 6 + Program_Err_7 = 0x0B, ///< Программная ошибка 7 + Program_Err_8 = 0x0C, ///< Программная ошибка 8 +}MB_MZKTEErrorsTypeDef; + + +/** + * @brief Сборный параметр + * @details Информация о состоянии МЗКТЭ + */ +typedef union //MB_MZKTEStatusTypeDef +{ + uint16_t all; ///< Доступ к регистру целиком + struct + { + unsigned TE_ErrActive:1; /*!< @brief Бит [0]: Авария на ТЭ + @details Состояния: + - 0 - напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария» + - 1 - напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария» */ + + unsigned TE_WarnActive:1; /*!< @brief Бит [1]: Предупреждения на ТЭ + @details Состояния: + - 0 - напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение» + - 1 - напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение» */ + + unsigned Opros_TE:1; /*!< @brief Бит [2]: Разрешение опроса ТЭ + @details Состояния: + - 0 – опрос ТЭ разрешен + - 1 – опрос ТЭ запрещен */ + + unsigned MZKTE_ErrStatus:2; /*!< @brief Биты [4:3]: Состояние МЗКТЭ + @details Состояния: + - 0 - МЗКТЭ функционирует нормально. Идет опрос ТЭ. + - 1 - неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции + (некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef) + - 2 - Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным + (ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef) */ + + unsigned reserved:3; ///< Биты [7:5] зарезервированны + + MB_MZKTEErrorsTypeDef MZKTE_Error:8; /*!< @brief Биты [15:8]: Номер неисправности МЗКТЭ + @details Номера неисправностей описаны в @ref MB_MZKTEErrorsTypeDef */ + }param; ///< Доступ к регистру по параметрам +}MB_MZKTEStatusTypeDef; + + + +/** + * @brief Входные регистры для контроля состояния МЗКТЭ + */ +typedef struct //MB_DataInRegsTypeDef +{ + + uint16_t U_TE[85]; /*!< @brief Адреса 0-84: Текущие значения напряжения ТЭ + @details Значения передаются умноженными на 1000 (т.е. если Uтэ = 0,625 В, то будет передано число 625) */ + + MB_MZKTEStatusTypeDef Status; /*!< @brief Адрес 85: Сборный параметр + @details Информация о состоянии МЗКТЭ @ref MB_MZKTEStatusTypeDef */ +}MB_DataInRegsTypeDef; + + +// DEFINES FOR REGISTERS ARRAYS +#define R_INREG_ADDR 0 +#define R_INREG_QNT 86 + +#define R_HOLDREG_ADDR 0 +#define R_HOLDREG_QNT 175 + + +// DEFINES FOR REGISTERS LOCAL ADDRESSES +//#define R_SET_ERROR(_te_num_) 0 + + +/** MODBUS_DATA_RERISTERS_DEFINES + * @} + */ + +//----------------DEFINES FOR COILS----------------- +/** + * @addtogroup MODBUS_DATA_COILS_DEFINES + * @ingroup MODBUS_DATA + * @brief Defines for coils + @verbatim + Структура дефайна + Для массивов коилов: + C__ADDR - модбас адресс первого коила в массиве + C__QNT - количество коилов в массиве (минимум 16) + + @endverbatim + * @{ + */ + + + +/** + * @brief Флаги исключения ТЭ из алгоритма формирования сигналов «Предупреждение» и «Авария» + * @details В случае установки нулевого значения конкретной ячейки значение напряжения ТЭ, + * связанного с этой ячейкой, не будет учитываться при формировании сигналов «Предупреждение» и «Авария» + */ +typedef struct //MB_DataCoilsTypeDef +{ + union + { + struct + { + uint64_t TE0_63; ///< Ячейки ТЭ №0-63 + uint32_t TE64_84:21; ///< Ячейки ТЭ №64-84 + }all; + struct + { + unsigned TE0_Exclude:1; + unsigned TE1_Exclude:1; + unsigned TE2_Exclude:1; + unsigned TE3_Exclude:1; + unsigned TE4_Exclude:1; + unsigned TE5_Exclude:1; + unsigned TE6_Exclude:1; + unsigned TE7_Exclude:1; + unsigned TE8_Exclude:1; + unsigned TE9_Exclude:1; + unsigned TE10_Exclude:1; + unsigned TE11_Exclude:1; + unsigned TE12_Exclude:1; + unsigned TE13_Exclude:1; + unsigned TE14_Exclude:1; + unsigned TE15_Exclude:1; + unsigned TE16_Exclude:1; + unsigned TE17_Exclude:1; + unsigned TE18_Exclude:1; + unsigned TE19_Exclude:1; + unsigned TE20_Exclude:1; + unsigned TE21_Exclude:1; + unsigned TE22_Exclude:1; + unsigned TE23_Exclude:1; + unsigned TE24_Exclude:1; + unsigned TE25_Exclude:1; + unsigned TE26_Exclude:1; + unsigned TE27_Exclude:1; + unsigned TE28_Exclude:1; + unsigned TE29_Exclude:1; + unsigned TE30_Exclude:1; + unsigned TE31_Exclude:1; + unsigned TE32_Exclude:1; + unsigned TE33_Exclude:1; + unsigned TE34_Exclude:1; + unsigned TE35_Exclude:1; + unsigned TE36_Exclude:1; + unsigned TE37_Exclude:1; + unsigned TE38_Exclude:1; + unsigned TE39_Exclude:1; + unsigned TE40_Exclude:1; + unsigned TE41_Exclude:1; + unsigned TE42_Exclude:1; + unsigned TE43_Exclude:1; + unsigned TE44_Exclude:1; + unsigned TE45_Exclude:1; + unsigned TE46_Exclude:1; + unsigned TE47_Exclude:1; + unsigned TE48_Exclude:1; + unsigned TE49_Exclude:1; + unsigned TE50_Exclude:1; + unsigned TE51_Exclude:1; + unsigned TE52_Exclude:1; + unsigned TE53_Exclude:1; + unsigned TE54_Exclude:1; + unsigned TE55_Exclude:1; + unsigned TE56_Exclude:1; + unsigned TE57_Exclude:1; + unsigned TE58_Exclude:1; + unsigned TE59_Exclude:1; + unsigned TE60_Exclude:1; + unsigned TE61_Exclude:1; + unsigned TE62_Exclude:1; + unsigned TE63_Exclude:1; + unsigned TE64_Exclude:1; + unsigned TE65_Exclude:1; + unsigned TE66_Exclude:1; + unsigned TE67_Exclude:1; + unsigned TE68_Exclude:1; + unsigned TE69_Exclude:1; + unsigned TE70_Exclude:1; + unsigned TE71_Exclude:1; + unsigned TE72_Exclude:1; + unsigned TE73_Exclude:1; + unsigned TE74_Exclude:1; + unsigned TE75_Exclude:1; + unsigned TE76_Exclude:1; + unsigned TE77_Exclude:1; + unsigned TE78_Exclude:1; + unsigned TE79_Exclude:1; + unsigned TE80_Exclude:1; + unsigned TE81_Exclude:1; + unsigned TE82_Exclude:1; + unsigned TE83_Exclude:1; + unsigned TE84_Exclude:1; + }bit; ///< Биты для доступа к каждой ячейке ТЭ + }Exclude; ///< Юнион для исключения ТЭ +}MB_DataCoilsTypeDef; + +// DEFINES FOR COIL ARRAYS +#define C_TE_EXCLUDE_ADDR 0 +#define C_TE_EXCLUDE_QNT 84 + +/** MODBUS_DATA_COILS_DEFINES + * @} + */ + + +//-----------MODBUS DEVICE DATA SETTING------------- +// MODBUS DATA STRUCTTURE +/** + * @brief Структура со всеми регистрами и коилами модбас + * @ingroup MODBUS_DATA + */ +typedef struct // mzkt modbus data +{ + MB_DataInRegsTypeDef InRegs; ///< Modbus input registers @ref MB_DataInRegsTypeDef + + MB_DataCoilsTypeDef Coils; ///< Modbus coils @ref MB_DataCoilsTypeDef + + MB_DataHoldRegsTypeDef HoldRegs; ///< Modbus holding registers @ref MB_DataHoldRegsTypeDef +}MB_DataStructureTypeDef; +extern MB_DataStructureTypeDef MB_DATA; + + + + + +///////////////////////////////////////////////////////////// +///////////////////////TEMP/OUTDATE/OTHER//////////////////// + +//typedef enum //MB_MZKTECommandsTypeDef +//{ +// StandartMode = 0x00, ///< Стандартная работа +// Opros_TE_Disable = 0x01, ///< Запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются) +//}MB_MZKTECommandsTypeDef; + +///** +// * @brief Состояние МЗКТЭ +// */ +//typedef enum //MB_MZKTEErrStatusTypeDef +//{ +// MZKTE_OK = 0x0, ///< МЗКТЭ функционирует нормально. Идет опрос ТЭ. +// NonCritical_Err = 0x1, ///< Неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции (некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef). +// Critical_Err = 0x2, ///< Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным (ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef) +// +//}MB_MZKTEErrStatusTypeDef; +//typedef enum +//{ +// TE_No_Err = 0x0, ///< Напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария» +// TE_Err = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария» +//}MB_TEErrActiveTypeDef; +//typedef enum +//{ +// TE_No_Warn = 0x0, ///< Напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение» +// TE_Warn = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение» +//}MB_TEWarnActiveTypeDef; +//typedef enum +//{ +// OprosTE_Enable = 0x0, ///< Опрос ТЭ разрешен +// OprosTE_Disable = 0x1, ///< Опрос ТЭ запрещен (см. регистр хранения 170) +//}MB_OprosTETypeDef; diff --git a/ТЗ/неофтз.txt b/ТЗ/неофтз.txt new file mode 100644 index 0000000..b3c42cd --- /dev/null +++ b/ТЗ/неофтз.txt @@ -0,0 +1,37 @@ + : . + +: +0x01 Read Coils +0x03 Read Holding Registers +0x04 Read Input Registers +0x05 Write Single Coil +0x06 Write Single Register +0x0F Write Multiple Coils +0x10 Write Multiple Registers + +.. : +- (MB_DataInRegsTypeDef), +- (MB_DataHoldRegsTypeDef), +- (MB_DataCoilsTypeDef). + + , , . typedef . , . + + + : + ( ), 85 . : . . + -. + + : +- - +- - . 4 , 85 : + - , + - "", + - "", + - + + . " ". 170-174. 0x06 (). 0x10 (). + + ( 0x04) + "" "" (0x03, 0x06, 0x10) + (0x03, 0x06) + (0x01, 0x05, 0x0F) \ No newline at end of file diff --git a/ТЗ/прил.MODBUS.pdf b/ТЗ/прил.MODBUS.pdf new file mode 100644 index 0000000..db739ee Binary files /dev/null and b/ТЗ/прил.MODBUS.pdf differ