本文适用于pc based的测控系统的上位机,定义了一套报警规则。
由5个部分组成:自定义4布尔类、在全局文件定义工位错误结构体和结构体变量,其它地方给此变量的当前值成员赋值,报警线程类、数据库保存类、弹框类。
1.自定义4布尔类
本类实现了上升沿和下降沿函数,得到信号的变化那1次。
(1)头文件(文件名:four_bl.h)
#ifndef FOUR_BL_H
 #define FOUR_BL_H
//#include <QObject>
class Four_bl
 {
     //Q_OBJECT
 public:
     bool current_Value=false;//当前值
 private:
     bool history_Value=false;//历史值
 public:
     Four_bl();
     bool Is_raise_edge();//上升沿
     bool Is_fall_edge();//下降沿
     void Refresh_history_Value();
     bool Get_history_Value();
 };
#endif // FOUR_BL_H
(2)cpp文件(文件名:four_bl.cpp)
#include "four_bl.h"
Four_bl::Four_bl() {}
 bool Four_bl::Is_raise_edge()//上升沿
 {
     return (current_Value && !history_Value);
 }
 bool Four_bl::Is_fall_edge()//下降沿
 {
     return (!current_Value && history_Value);
 }
 void Four_bl::Refresh_history_Value()//刷新历史值
 {
     history_Value=current_Value;
 }
 bool Four_bl::Get_history_Value()//得到历史值
 {
     return history_Value;
 }
2.在全局文件中
(1) 头文件中添加(文件名:global_def.h)
struct staion_error
 { 
      Four_bl motor_error;//马达故障
      Four_bl negative_limit;//负限位
      Four_bl positive_limit;//正限位
      //...有多少就定义多少
 };
extern staion_error global_staion_error_array[3];//工位故障数组,你有多少个工位就写多少长度
(2) cpp文件(文件名:global_def.cpp)
staion_error global_staion_error_array[3];//与头文件中那个数组长度要一样
3.给此变量的当前值成员赋值
 for(int i=0;i<3;i++)
      {
    global_staion_error_array[i].motor_error.current_Value=  ;//补上右边
     global_staion_error_array[i].positive_limit.current_Value= ;//补上右边
     global_staion_error_array[i].negative_limit.current_Value= ;//补上右边
}
4.报警线程类
(1)头文件(文件名:alarm_thread.h)
#ifndef ALARM_THREAD_H
 #define ALARM_THREAD_H
 #include <QObject>
 #include <QThread>
 #include <QDebug>
 #include <QString>
 //#include <QCoreApplication>
 #include "global_def.h"
 #include <QMutexLocker>
 #include <datapoolpage.h>
 class Alarm_Thread :  public QThread
 {
     Q_OBJECT
 private:
     bool    m_paused=true;  //暂停
     bool    m_stop=false;   //停止线程run()
     long    Seq=0;//序次
 protected:
      void    run();      //线程的事件循环
 public:
    void    Begin();    //开始
     void    Pause();    //暂停
     void    stopThread();   //结束线程run()
     explicit Alarm_Thread(QObject *parent = nullptr);
signals:
 private slots:
     void ChangeState(QString cmd);
 };
#endif // ALARM_THREAD_H
(2) cpp文件(文件名:alarm_thread.cpp)
#include "alarm_thread.h"
Alarm_Thread::Alarm_Thread(QObject *parent)
    : QThread{parent}
 {}
 void Alarm_Thread::run()      //线程的事件循环
 {  // qDebug()<<"void Alarm_Thread::run() ";
     while(!m_stop)      //循环主体
     {
         //QElapsedTimer time_m;
         //time_m.start();
          QThread::msleep(2000);
         if (!m_paused)
         {
             //qDebug()<<"void Alarm_Thread::run()-while loop-- ";
             //return;
            for(int i=0;i<3;i++)
             {
             if(global_staion_error_array[i].motor_error.Is_raise_edge())//如果是上升沿
             {
                  //DataPoolPage::insert_alarm(i+1,"",1);//插入报警信息到数据库的
            }
             if(global_staion_error_array[i].motor_error.Is_fall_edge())
             {   QString st_name_array[]={"","工位1","工位2","工位3"};
                 //DataPoolPage::update_alarm(st_name_array[i+1],1);//更新数据库的
                 qDebug()<<"--------------------------------";
                 qDebug()<<st_name_array[i+1];
             }
             global_staion_error_array[i].motor_error.Refresh_history_Value();
            //这行要在上升沿处理和下降沿处理以后
             //----------------------------------------------------------------------
             if(global_staion_error_array[i].negative_limit.Is_raise_edge())
             {
                 //DataPoolPage::insert_alarm(i+1,"",2);//插入数据库的
            }
             if(global_staion_error_array[i].negative_limit.Is_fall_edge())
             {   QString st_name_array[]={"","工位1","工位2","工位3"};
                 //DataPoolPage::update_alarm(st_name_array[i+1],2);//更新数据库的
            }
             global_staion_error_array[i].negative_limit.Refresh_history_Value();
             //------------------------------------------------------------------------
             if(global_staion_error_array[i].positive_limit.Is_raise_edge())
             {
                 //DataPoolPage::insert_alarm(i+1,"",3);//插入数据库的
            }
             if(global_staion_error_array[i].positive_limit.Is_fall_edge())
             {   QString st_name_array[]={"","工位1","工位2","工位3"};
                // DataPoolPage::update_alarm(st_name_array[i+1],3);//更新数据库的
            }
             global_staion_error_array[i].positive_limit.Refresh_history_Value();
            if(global_staion_error_array[i].no_on_error.Is_raise_edge())
             {
                 //DataPoolPage::insert_alarm(i+1,"",4);//插入数据库的
            }
            //..继续添加你的
        }
         else
         {
             //qDebug()<<"void Alarm_Thread::run()-while loop--pause ";
              QThread::msleep(800);
         }
         QThread::msleep(2000);
     }
 }
 void Alarm_Thread::Begin()    //开始
 {
     m_paused=false;
 }
 void Alarm_Thread::Pause()    //暂停
 {
     m_paused=true;
 }
 void Alarm_Thread::stopThread()   //结束线程run()
 {
     m_stop=true;
 }
 void Alarm_Thread::ChangeState(QString cmd)
 {
     if(cmd=="begin")
     {
         Begin();
     }
     else if(cmd=="pause")
     {
         Pause();
     }
 }
5.数据库和写入数据库的类
5.1建立数据库和表

5.2 写入数据库的类
(1)头文件(文件名:datapoolpage.h)
#ifndef DATAPOOLPAGE_H
 #define DATAPOOLPAGE_H
#include <QWidget>
 #include <QSqlDatabase>
 #include <QSqlError>
 #include <QSqlQuery>
 #include <QElapsedTimer>
 #include <QDateTime>
 #include <iostream>
 #include <QMutexLocker>
 #include "global_def.h"
 namespace Ui {
 class DataPoolPage;
 }
class DataPoolPage : public QWidget
 {
     Q_OBJECT
public:
     explicit DataPoolPage(QWidget *parent = nullptr);
     ~DataPoolPage();
     //QSqlDatabase database;
     void static insert_alarm(QString st,QString info1,QString info2,QDateTime dt,QString status_,int num);
     void static insert_alarm(int st_num,QString info2,int num);
     void static update_alarm(QString st,int num);
  
 private slots:
  
private:
     Ui::DataPoolPage *ui;
     int seq=1;
 };
#endif // DATAPOOLPAGE_H
  
(2)cpp文件(文件名:datapoolpage.cpp)
#include "datapoolpage.h"
 #include "ui_datapoolpage.h"
DataPoolPage::DataPoolPage(QWidget *parent)
     : QWidget(parent)
     , ui(new Ui::DataPoolPage)
 {
     ui->setupUi(this);
     //db = QSqlDatabase::addDatabase("QMYSQL");
}
DataPoolPage::~DataPoolPage()
 {
     delete ui;
 }
void DataPoolPage::insert_alarm(QString st,QString info1,QString info2,QDateTime dt,QString status_,int num)
 {    qDebug()<<"-insert_alarm2-----"<<st;
     //qDebug()<<QSqlDatabase::drivers();
     //QMutexLocker locker(&g_mutx_db);
     if(QSqlDatabase::contains("MySQLConnection1"))
         QSqlDatabase::removeDatabase("MySQLConnection1");
     QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "MySQLConnection1");
     db.setHostName("127.0.0.1");
     db.setPort(3306);
     db.setDatabaseName("deviceinfodb");//你自己的数据库名称
     db.setUserName("root");
     db.setPassword("123456");
     if (!db.open()) {
         qDebug()<<"不能连接"<<"connect to mysql error"<<db.lastError().text();
         db.close();
         return ;
     }
     else
     {
         qDebug()<<"数据库连接成功";
     }
     QDateTime now = QDateTime::currentDateTime();
     QSqlQuery query(db);
    query.prepare("INSERT INTO current_alarms (workstation, description, description2,start_time, status,code) VALUES (:value0,:value1, :value2, :value3, :value4, :value5)");
     query.bindValue(":value0",st );
     query.bindValue(":value1", info1);
     query.bindValue(":value2", info2);
     query.bindValue(":value3", dt);
     query.bindValue(":value4", status_);
     query.bindValue(":value5", num);
  //query.bindValue(":value4", "active");
     if (!query.exec())
    {
         qDebug() << "Failed to insert data. Error: " << query.lastError().text();
         db.close();
         return  ;
     }
     qDebug() << "Data inserted successfully";
     db.close();
 }
 void DataPoolPage::update_alarm(QString st,int num)
 {
   //UPDATE `deviceinfodb`.`current_alarms` SET  `status` = 'active', `resolved_time` = now() , `code` = 00000000001 WHERE `code`=1 and `status`='active' ;
     qDebug()<<"void DataPoolPage::update_alarm(QString st,int num)";
     //qDebug()<<QSqlDatabase::drivers();
      //return;
      QMutexLocker locker(&g_mutx_db);
      //QSqlDatabase db= QSqlDatabase::addDatabase("QMYSQL");
     //QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "MySQLConnection");
      if(QSqlDatabase::contains("MySQLConnection2"))
          QSqlDatabase::removeDatabase("MySQLConnection2");
      QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "MySQLConnection2");
    db.setHostName("127.0.0.1");
     db.setPort(3306);
     db.setDatabaseName("deviceinfodb");//你自己的数据库名称
     db.setUserName("root");
     db.setPassword("123456");
    if (!db.open()) {
         qDebug()<<"不能连接"<<"connect to mysql error"<<db.lastError().text();
         db.close();
         return ;
     }
     else
     {
         qDebug()<<"数据库连接成功";
     }
     QDateTime now = QDateTime::currentDateTime();
     QSqlQuery query(db);
    query.prepare("UPDATE current_alarms SET  status = 'resolved', resolved_time = now()  WHERE workstation =:value0 and code=:value1 and status='active' ");
     query.bindValue(":value0",st );
     query.bindValue(":value1",num );
     //query.bindValue(":value4", "active");
     if (!query.exec())
    {
         qDebug() << "Failed to insert data. Error: " << query.lastError().text();
         db.close();
         return  ;
     }
     qDebug() << "Data update successfully";
     db.close();
 }
//说明,弹框类,在下篇文章中描述
  



















