QT c++ 测控系统 一套报警规则(上)

news2025/2/27 17:08:43

本文适用于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();
}

//说明,弹框类,在下篇文章中描述
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2261251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

概率论得学习和整理24:EXCEL的各种图形,统计图形

目录 0 EXCEL的各种图形&#xff0c;统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图&#xff0c;一般是只选中1列数据&#xff08;1个数组&#xff09; 1.3 如何修改频度图的宽度 1.4 hist图的一个特…

项目二十三:电阻测量(需要简单的外围检测电路,将电阻转换为电压)测量100,1k,4.7k,10k,20k的电阻阻值,由数码管显示。要求测试误差 <10%

资料查找&#xff1a; 01 方案选择 使用单片机测量电阻有多种方法&#xff0c;以下是一些常见的方法及其原理&#xff1a; 串联分压法&#xff08;ADC&#xff09; 原理&#xff1a;根据串联电路的分压原理&#xff0c;通过测量已知电阻和待测电阻上的电压&#xff0c;计算出…

Linux中 vim 常用命令大全详细讲解

文章目录 前言一、Vim 基本操作 &#x1f579;️1.1 打开或创建1.2 退出编辑1.3 模式切换 二、Vim 光标移动命令 ↕️2.1 基本移动2.2 行内移动2.3. 单词移动2.4. 页面移动2.5. 行跳转 三、Vim 文本编辑命令 &#x1f4cb;3.1 插入和删除3.2 复制、剪切与粘贴3.3 替换与修改 四…

ARM架构服务器国产麒麟V10安装nginx

目前ARM架构服务器越来越多的出现在我们的工作中&#xff0c;尤其大数据时代的需要&#xff0c;服务器操作系统linux国产化进程的推进。本人已经编写了很多ARM架构下安装java环境&#xff0c;安装mysql&#xff0c;安装redis等等的文档。现在我们演示一下国产麒麟V10安装nginx-…

【SQL】语句练习

1. 更新 1.1单表更新 例1: 所有薪水低于30000的员工薪水增加10% SQL命令&#xff1a; update employee set salarysalary*1.1 where salary < 30000; 1.2多表更新 例1: 将下图两表张三的语文成绩从95修改为80 SQL命令&#xff1a; update exam set score80 where subjec…

【开源】使用环信UIKit for uniapp 做一个IM即时聊天应用

环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界面、联系人列表及后续界面等功能&#xff0c;帮助开发者根据实际业务需求快速搭建包含 UI 界面的即时通讯应用。 本文教大家使用环信 uniapp UIKit 快…

用 Python Turtle 绘制经典杰瑞鼠:捕捉卡通世界中的小聪明

用 Python Turtle 绘制经典杰瑞鼠&#xff1a;捕捉卡通世界中的小聪明 &#x1f438; 前言 &#x1f438;&#x1f41e;往期绘画>>点击进所有绘画&#x1f41e;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f438; 前言 &#x1f438; 杰…

Excel拆分脚本

Excel拆分 工作表按行拆分为工作薄 工作表按行拆分为工作薄 打开要拆分的Excel文件&#xff0c;使用快捷键&#xff08;AltF11&#xff09;打开脚本界面&#xff0c;选择要拆分的sheet&#xff0c;打开Module&#xff0c;在Module中输入脚本代码&#xff0c;然后运行脚本 Su…

ModStartCMS v9.1.0 数据Grid样式优化,富文本格式刷支持,精简代码

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

2024年12月16日Github流行趋势

项目名称&#xff1a;PDFMathTranslate 项目维护者&#xff1a;Byaidu reycn hellofinch Wybxc YadominJinta项目介绍&#xff1a;基于 AI 完整保留排版的 PDF 文档全文双语翻译&#xff0c;支持 Google/DeepL/Ollama/OpenAI 等服务&#xff0c;提供 CLI/GUI/Docker。项目star数…

3-机器人视觉-机器人抓取与操作

文章目录 3机器人视觉目录 1. 传感器和标定摄像头模型Intrinsic MatrixExtrinsic Matrix 标定内参标定手眼标定和外参标定 力传感器&其它传感器其它传感器 2. 神经网络和图像处理2D特征处理常见架构 训练流程推理流程部署流程2D 图像任务3D Point Cloud FeaturePointNet Ap…

Java String详解(二)

上一篇博客&#xff1a;Java String详解&#xff08;一&#xff09; 写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blo…

Qt之点击鼠标右键创建菜单栏使用(六)

Qt开发 系列文章 - menu&#xff08;六&#xff09; 目录 前言 一、示例演示 二、菜单栏 1.MenuBar 2.Menu 总结 前言 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏&#xff08;menubar&#xff09;、多个工具栏(toolbars)、一个状态栏(status…

《拉依达的嵌入式\驱动面试宝典》—C/CPP基础篇(一)

《拉依达的嵌入式\驱动面试宝典》—C/CPP基础篇(一) 你好&#xff0c;我是拉依达。 感谢所有阅读关注我的同学支持&#xff0c;目前博客累计阅读 27w&#xff0c;关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析&#xff08;持续更新&#xff09;-CSDN博客》已经是 Lin…

IntelliJ IDEA(2024版) 的安装、配置与使用教程:常用配置、创建工程等操作(很详细,你想要的都在这里)

IDEA的安装、配置与使用&#xff1a; Ⅰ、IDEA 的安装&#xff1a;1、IDEA 的下载地址(官网)&#xff1a;2、IDEA 分为两个版本&#xff1a;旗舰版 (Ultimate) 和 社区版 (Community)其一、两个不同版本的安装文件&#xff1a;其二、两个不同版本的详细对比&#xff1a; 3、IDE…

MybatisPlus-配置加密

配置加密 目前配置文件中的很多参数都是明文&#xff0c;如果开发人员发生流动&#xff0c;很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。 我们以数据库的用户名和密码为例。 生成秘钥 首先&#xff0c;我们利用AES工具生成一个随机秘钥&#…

深度学习基础--将yolov5的backbone模块用于目标识别会出现怎么效果呢??

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 yolov5网络结构比较复杂&#xff0c;上次我们简要介绍了yolov5网络模块&#xff0c;并且复现了C3模块&#xff0c;深度学习基础–yolov5网络结构简介&a…

数据结构---图(Graph)

图&#xff08;Graph&#xff09;是一种非常灵活且强大的数据结构&#xff0c;用于表示实体之间的复杂关系。在图结构中&#xff0c;数据由一组节点&#xff08;或称为顶点&#xff09;和连接这些节点的边组成。图可以用于表示社交网络、交通网络、网络路由等场景。 1. 基本概…

人工智能技术的深度解析与推广【人工智能的应用场景】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

软件开发中 Bug 为什么不能彻底消除

在软件开发中&#xff0c;Bug无法彻底消除的原因主要包括&#xff1a;软件复杂度高、人员认知与沟通受限、需求和环境不断变化、工具与测试覆盖不足、经济与时间成本制约。其中“需求和环境不断变化”尤为关键&#xff0c;因为在实际开发中&#xff0c;业务逻辑随着市场与用户反…