Qt preparation of gas safety management system management controller 20

I. Introduction

Controller management, mainly to add and delete and modify controller, including the serial number, port name, controller name, address controller, controller model, the number of detectors these fields, the name of the port which represents the current controller belongs port, a system may have a good multiple ports, a port may correspond to a plurality of controllers, a controller can access a plurality of detectors. This parameter is the number of probes mainly to facilitate issued data, the data to know in advance how many detectors to take, make up hair down under the corresponding data packet, it can avoid invalid data, such as the following is a 16 detectors, to it is not necessary to fetch the data detector 255, there is no meaning to get, after all the rest are all 0, but also increases the burden on the communication bus, bus lane garbage data occupancy.

And a controller communication port information is not stored interval, the node to the probe endmost only requires storage interval, each detector node can set a different storage interval needed are interactive communication system and a controller in communication under the communication port, once the controller is down, all the controllers are dropped below the detector, once the blocked port, the port controllers are all dropped, cascade layers .

Skin Open Source: https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo
File name: styledemo

Experience Address: https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe
File name: bin_sams.zip

Second, the functional characteristics

  1. Collect data port, serial port support + network port, serial port supports baud rate set free + serial number, network support freely set the IP address + communication ports, each port supports acquisition cycle, default 1 second address, set the communication timeout support frequency default 3 times, support the largest reconnection time for the re-read off-line equipment.
  2. Controller information, the controller can be added to the name, address + control model selection controller, the controller is provided below the number of detectors.
  3. Probe information, the bit number can be added, can be freely selected probe type, gas type, gas symbol, the value of the high alarm, low reported values, buffer values, a value is cleared, if enabled, an alarm sound, a background map, the storage period, the value conversion of decimal places, the alarm delay time, alarm type (HH, LL, HL) and the like.
  4. Detector Model Controller Model + + + gas symbol gas species, can be freely arranged.
  5. Map supports importing and delete all the corresponding map position detector can freely drag saved.
  6. Port information + + probe information controller information, import and export support + + print exported to Excel.
  7. + + Alarm log record recording the user, the query condition combination to support multiple, such as + period + Controller detectors, all record print support exported to Excel +.
  8. Export to excel record of support for all forms such as excel + wps file versions, does not rely on software such as excel.
  9. You can delete data within a specified time frame, auto clean up early data, set the maximum number of record-keeping.
  10. Support forwarding alarm messages, the plurality of support receiving phone number, the transmission interval can be set, such as instant or the transmission 6 hours send all the alarm messages, message content is too long, a number of messages automatically split.
  11. Support alarm mail forwarding, support for receiving a plurality of mailboxes, the transmission interval can be set, such as instant transmission or six hours all the alarm information once transmitted, to support attachments.
  12. High + Low message packets Color Color values ​​Color + + + 0 normal color profile curves + background color, etc., can be freely selected.
  13. Software English title Chinese title + + + logo Copyright paths can be freely set.
  14. Provides switch switched on the alarm sound + + + automatic login remember passwords.
  15. Sound the alarm can be set to play frequency interface available in 17 skin file selection.
  16. Support cloud data synchronization, cloud database information can be set, such as database name, username + password.
  17. Support network forwarding and receiving network, the network is open to receive, parse udp software to receive data from. Network forwarding support multiple target IP, thus achieving a local collection of software, free data to the client, at any time to view the detector data.
  18. Automatically remembers the last stop of the user interface + additional information, automatic application restart.
  19. Alarm automatically switches to a map corresponding to the detector button flashes.
  20. Double-click the probe icon, you can back control.
  21. Support user rights management, administrators + operator into two categories, user login + user exits, you can remember the password and automatic login, more than three times error prompt and close the program.
  22. Supports four monitoring mode, the monitoring device panel monitor + Map + table + curve data monitoring data monitoring, are free to switch the four synchronization application.
  23. Support alarm relay linkage, a bit serial number can be linked across a plurality of modules and a relay number, support-many.
  24. Local data storage support sqlite + mysql, supports remote data synchronization to the cloud database. Automatic reconnection.
  25. Real-time local device collected data uploaded to the cloud, so that the phone APP or web and other ways to extract.
  26. Supports two data sources, one serial port and the data acquisition devices through a network protocol, one is the collection database. Acquisition mode database can be used as a general system.
  27. Carrying equipment simulation tools, devices 16 support analog data, but also with the database data simulation, when there is no data to test the device.
  28. Default communication protocol using modbus protocol, later adding support mqtt and other things of the agreement, made common system.
  29. Supports all windows operating system + linux operating system and other operating systems.

Third, renderings

Fourth, the core code

#include "frmconfigdevice.h"
#include "ui_frmconfigdevice.h"
#include "quiwidget.h"
#include "dbhelper.h"
#include "dbdelegate.h"
#include "excelapi.h"
#include "printapi.h"
#include "api.h"

frmConfigDevice::frmConfigDevice(QWidget *parent) : QWidget(parent), ui(new Ui::frmConfigDevice)
{
    ui->setupUi(this);
    this->initForm();
    this->initData();
    this->changeStyle();
}

frmConfigDevice::~frmConfigDevice()
{
    delete ui;
}

void frmConfigDevice::showEvent(QShowEvent *)
{
    model->select();
}

void frmConfigDevice::initForm()
{
    API::initTableView(ui->tableView);
    ui->widgetTop->setProperty("flag", "navbtn");
    if (QUIHelper::deskWidth() < 1440) {
        ui->labTip->setText("提示 → 改动后需重启应用");
    } else {
        ui->labTip->setText("提示 → 必须和现场控制器信息一致,改动后需重启应用");
    }    
}

void frmConfigDevice::initData()
{
    model = new QSqlTableModel(this);
    model->setTable("DeviceInfo");
    model->setSort(0, Qt::AscendingOrder);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();

    ui->tableView->setModel(model);
    ui->tableView->setProperty("model", true);

    columnNames.clear();
    columnNames << "编号" << "端口名称" << "控制器名称" << "控制器地址" << "控制器型号" << "探测器数量";

    columnWidths.clear();
    columnWidths << 80 << 120 << 170 << 80 << 170 << 80;

    for (int i = 0; i < columnNames.count(); i++) {
        model->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
        ui->tableView->setColumnWidth(i, columnWidths.at(i));
    }

    //编号委托
    QStringList deviceID;
    for (int i = 1; i <= 255; i++) {
        deviceID.append(QString::number(i));
    }

    DbDelegate *d_cbox_deviceID = new DbDelegate(this);
    d_cbox_deviceID->setDelegateType("QComboBox");
    d_cbox_deviceID->setDelegateValue(deviceID);
    //ui->tableView->setItemDelegateForColumn(0, d_cbox_deviceID);

    //通信端口委托
    d_cbox_portName = new DbDelegate(this);
    d_cbox_portName->setDelegateType("QComboBox");
    ui->tableView->setItemDelegateForColumn(1, d_cbox_portName);
    portNameChanged();

    //设备地址委托
    QStringList deviceAddr;
    for (int i = 1; i <= 255; i++) {
        deviceAddr.append(QString::number(i));
    }

    DbDelegate *d_cbox_deviceAddr = new DbDelegate(this);
    d_cbox_deviceAddr->setDelegateType("QComboBox");
    d_cbox_deviceAddr->setDelegateValue(deviceAddr);
    ui->tableView->setItemDelegateForColumn(3, d_cbox_deviceAddr);

    //控制器型号委托,关联控制器型号,下拉变化右侧值改动
    d_cbox_deviceType = new DbDelegate(this);
    connect(d_cbox_deviceType, SIGNAL(valueChanged(QString)), this, SLOT(typeValueChanged(QString)));
    d_cbox_deviceType->setDelegateType("QComboBox");
    ui->tableView->setItemDelegateForColumn(4, d_cbox_deviceType);
    deviceTypeChanged();

    //探测器数量委托
    DbDelegate *d_txt_nodeNumber = new DbDelegate(this);
    d_txt_nodeNumber->setDelegateType("QLineEdit");
    if (App::WorkMode == 0) {
        d_txt_nodeNumber->setDelegateEnable(false);
    } else {
        connect(d_txt_nodeNumber, SIGNAL(valueChanged(QString)), this, SLOT(numberValueChanged(QString)));
    }
    //connect(d_txt_nodeNumber, SIGNAL(valueChanged(QString)), this, SLOT(numberValueChanged(QString)));
    ui->tableView->setItemDelegateForColumn(5, d_txt_nodeNumber);

    //用来切换样式自动改变颜色
    delegates << d_cbox_deviceID;
    delegates << d_cbox_portName;
    delegates << d_cbox_deviceAddr;
    delegates << d_cbox_deviceType;
    delegates << d_txt_nodeNumber;
}

void frmConfigDevice::changeStyle()
{
    foreach (DbDelegate *delegate, delegates) {
        delegate->setTextColor(QUIConfig::TextColor);
        delegate->setSelectBgColor(QUIConfig::NormalColorStart);
    }
}

void frmConfigDevice::deviceTypeChanged()
{
    d_cbox_deviceType->setDelegateValue(DBData::TypeInfo_DeviceType);    
}

void frmConfigDevice::portNameChanged()
{
    d_cbox_portName->setDelegateValue(DBData::PortInfo_PortName);
}

void frmConfigDevice::typeValueChanged(const QString &value)
{
    //自动设置最大探测器数量
    int nodeNumber = 8;
    int index = DBData::TypeInfo_DeviceType.indexOf(value);
    if (index >= 0) {
        nodeNumber = DBData::TypeInfo_NodeNumber.at(index);
    }

    int row = ui->tableView->currentIndex().row();
    model->setData(model->index(row, 5), nodeNumber);
}

void frmConfigDevice::numberValueChanged(const QString &value)
{
    //判断填写的最大值是否超过
    int row = ui->tableView->currentIndex().row();
    QString deviceType = model->index(row, 4).data().toString();
    int index = DBData::TypeInfo_DeviceType.indexOf(deviceType);
    if (index >= 0) {
        int nodeNumber = DBData::TypeInfo_NodeNumber.at(index);
        if (value.toInt() > nodeNumber) {
            model->setData(model->index(row, 5), nodeNumber);
            QUIHelper::showMessageBoxError(QString("当前控制器最大探测器数量为 %1 !\n请重新输入!").arg(nodeNumber));
        }
    }
}

void frmConfigDevice::on_btnAdd_clicked()
{
    int count = model->rowCount();
    model->insertRow(count);

    int deviceID = model->index(count - 1, 0).data().toInt() + 1;
    QString portName = model->index(count - 1, 1).data().toString();
    QString deviceName = model->index(count - 1, 2).data().toString();
    int deviceAddr = model->index(count - 1, 3).data().toInt() + 1;
    QString deviceType = model->index(count - 1, 4).data().toString();
    int nodeNumber = model->index(count - 1, 5).data().toInt();

    if (deviceName.endsWith("#调度室控制器")) {
        deviceName = QString("%1#调度室控制器").arg(deviceAddr);
    }

    //设置第一条数据,在没有上一条参考数据时
    if (count == 0) {
        deviceID = 1;
        portName = DBData::PortInfo_Count > 0 ? DBData::PortInfo_PortName.first() : "通信端口-1";
        deviceName = "1#调度室控制器";
        deviceAddr = 1;
        deviceType = "FC-1003-8";
        nodeNumber = 8;

        if (App::WorkMode == 2) {
            deviceName = "默认控制器";
            deviceType = "WF-1000";
            nodeNumber = 16;
        }
    }

    //设置新增加的行默认值
    model->setData(model->index(count, 0), deviceID);
    model->setData(model->index(count, 1), portName);
    model->setData(model->index(count, 2), deviceName);
    model->setData(model->index(count, 3), deviceAddr);
    model->setData(model->index(count, 4), deviceType);
    model->setData(model->index(count, 5), nodeNumber);
    ui->tableView->setCurrentIndex(model->index(count, 0));
}

void frmConfigDevice::on_btnSave_clicked()
{
    model->database().transaction();
    if (model->submitAll()) {
        model->database().commit();
        DBHelper::loadDeviceInfo();

        //先同步探测器表的控制器名称
        emit deviceNameChanged();
    } else {
        model->database().rollback();
        QUIHelper::showMessageBoxError("保存信息失败,信息不能为空,请重新填写!");
    }
}

void frmConfigDevice::on_btnDelete_clicked()
{
    if (ui->tableView->currentIndex().row() < 0) {
        QUIHelper::showMessageBoxError("请选择要删除的控制器!");
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("确定要删除该控制器吗? 控制器对应的所有探测器都会被删除!") == QMessageBox::Yes) {
        int row = ui->tableView->currentIndex().row();
        QString deviceName = model->index(row, 2).data().toString();
        DBHelper::deleteNodeInfo(deviceName);

        model->removeRow(row);
        model->submitAll();

        int count = model->rowCount();
        ui->tableView->setCurrentIndex(model->index(count - 1, 0));
    }
}

void frmConfigDevice::on_btnReturn_clicked()
{
    model->revertAll();
}

void frmConfigDevice::on_btnClear_clicked()
{
    int count = model->rowCount();
    if (count <= 0) {
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("确定要清空所有控制器信息吗?") == QMessageBox::Yes) {
        DBHelper::clearDeviceInfo();
        model->select();
    }
}

void frmConfigDevice::on_btnExcel_clicked()
{
    QString name = "控制器信息";
    QString fileName = QString("%1_%2").arg(name).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"));
    QString file = API::getSaveFileNames(fileName, "Excel(*.xls)");
    if (file.isEmpty()) {
        return;
    }

    QString columns = "DeviceID,PortName,DeviceName,DeviceAddr,DeviceType,NodeNumber";
    QString where = "order by DeviceID asc";
    QStringList content = DBHelper::getContent("DeviceInfo", columns, where, "", ";");

    int rowCount = content.count();
    if (rowCount == 0) {
        QUIHelper::showMessageBoxError("没有要处理的数据!");
        return;
    }

    ExcelAPI::Instance()->saveExcel(file, name, name, "", columnNames, columnWidths, content);
    QString msg = QString("导出%1到Excel").arg(name);
    DBHelper::addUserLog("用户操作", msg);

    if (QUIHelper::showMessageBoxQuestion(msg + "成功!确定现在就打开吗?") == QMessageBox::Yes) {
        QString url = QString("file:///%1").arg(file);
        QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
    }
}

void frmConfigDevice::on_btnPrint_clicked()
{
    QString name = "控制器信息";
    QString columns = "DeviceID,PortName,DeviceName,DeviceAddr,DeviceType,NodeNumber";
    QString where = "order by DeviceID asc";
    QStringList content = DBHelper::getContent("DeviceInfo", columns, where, "", ";");

    int rowCount = content.count();
    if (rowCount == 0) {
        QUIHelper::showMessageBoxError("没有要处理的数据!");
        return;
    }

    PrintAPI::Instance()->print(name, "", columnNames, columnWidths, content);
    QString msg = QString("打印%1").arg(name);
    DBHelper::addUserLog("用户操作", msg);
}

void frmConfigDevice::on_btnInput_clicked()
{
    QString fileName;
    bool ok = DBHelper::inputData(columnNames.count(), App::FileFilter, "DeviceInfo", fileName, QUIHelper::appPath() + "/db", true);
    if (!fileName.isEmpty()) {
        DBHelper::addUserLog("用户操作", "导入控制器信息");
        if (ok) {
            QUIHelper::showMessageBoxInfo("导入控制器信息成功!", 3);
            model->select();
        } else {
            QUIHelper::showMessageBoxError("导入控制器信息失败!", 3);
        }
    }
}

void frmConfigDevice::on_btnOutput_clicked()
{
    QString columns = "*";
    QString where = "order by DeviceID asc";
    QString title = columnNames.join(App::FileSpliter);
    QStringList content = DBHelper::getContent("DeviceInfo", columns, where, title);

    QString fileName;
    bool ok = DBHelper::outputData("控制器信息", App::FileFilter, content, fileName, QUIHelper::appPath() + "/db");
    if (!fileName.isEmpty()) {
        DBHelper::addUserLog("用户操作", "导出控制器信息");
        if (ok) {
            QUIHelper::showMessageBoxInfo("导出控制器信息成功!", 3);
        } else {
            QUIHelper::showMessageBoxError("导出控制器信息失败!", 3);
        }
    }
}

Guess you like

Origin www.cnblogs.com/feiyangqingyun/p/11947397.html