当前位置:   article > 正文

【Qt\C++】二维图形化故障树

【Qt\C++】二维图形化故障树


一、故障树是什么?

故障树是一种用于分析系统故障原因和影响的图形化工具。它将系统故障视为从基础事件开始的一系列逻辑路径,通过特定的逻辑关系和逻辑运算符连接不同的事件,形成树状结构。故障树的根节点代表了系统的顶级故障事件,叶节点代表了系统的基础事件或故障事件的最小发生概率。通过分析故障树的逻辑路径,可以确定导致系统故障的主要原因和潜在的影响,从而采取相应的措施来提高系统的可靠性和安全性。故障树分析常用于工程领域,尤其是在安全、可靠性和风险评估方面。

二、相关知识点

1、Qt的MVC模型使用以及如何自定义model
2、Qt的XML读写
3、Qt的二维图形视图的使用以及如何自定义Item

三、生成故障树

1、故障树节点

故障树节点,也称为故障树事件,是故障树分析中的一种元素,用于表示故障发生的可能性。故障树节点可以是基本事件、中间事件或顶事件。

底事件:表示已知的故障或故障模式,是故障树的叶子节点。基本事件可以是具体故障的发生,也可以是系统的性能指标达到一定条件。 例如:
电路故障
传感器故障
控制器故障

中间事件:表示发生故障的可能性,是故障树的非叶子节点。中间事件由其他事件组合而成,可以通过多个基本事件或中间事件进行逻辑运算得到。 例如:
电路短路
传感器失效
控制器错误

顶事件:表示整个系统发生故障的可能性,是故障树的根节点。顶事件可以通过多个中间事件进行逻辑运算得到。 例如:
系统崩溃
故障发生
故障树节点之间通过逻辑门(如与门、或门、非门)进行逻辑关系的连接,形成逻辑上的故障发生路径,从顶事件到基本事件的逻辑路径可以用来分析系统中故障产生的原因。

2、定义故障树的树状结构以及读取保存

1.使用QTreeView和QStandardItemModel来显示故障树

模型代码头文件:

#include <QStandardItemModel>
#include <QXmlStreamWriter>
#include "items.h"

#define ITEMTYPE Qt::UserRole + 1
#define FAULTMSG Qt::UserRole + 2

class StandardTreeModel : public QStandardItemModel
{
   
    Q_OBJECT
public:
    static items::ItemType toType(int i);
    enum Insert {
   AtTopLevel, AsChild};
    explicit StandardTreeModel(QObject *parent = 0);
    QStandardItem *insertIndex(Insert insert, const QString &name, const QModelIndex &index, items::ItemType type);
    void save(const QString &fileName);
    void load(const QString &fileName);
private:
    void clear();
    void initialize();
    QStandardItem *createNewIndex(QStandardItem *root, const QString &name, items::ItemType type);
    void writeIndexAndChildren(QXmlStreamWriter *writer, QStandardItem *root);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

模型代码源文件:

#include "standardtreemodel.h"

#include <QFile>
#include <QXmlStreamWriter>
#include <QStack>
#include <QDebug>

items::ItemType StandardTreeModel::toType(int i)
{
   
    switch (i) {
   
    case 0:
        return items::topOr;
    case 1:
        return items::topAnd;
    case 2:
        return items::midOr;
    case 3:
        return items::midAnd;
    case 4:
        return items::bottom;
    }
    return items::unknown;
}

StandardTreeModel::StandardTreeModel(QObject *parent) : QStandardItemModel(parent)
{
   
    initialize();
}

void StandardTreeModel::initialize()
{
   
    setHorizontalHeaderLabels(QStringList() << "col1" << "col2");
}

void StandardTreeModel::clear()
{
   
    QStandardItemModel::clear();
    initialize();
}

QStandardItem *StandardTreeModel::insertIndex(StandardTreeModel::Insert insert, const QString &name, const QModelIndex &index, items::ItemType type)
{
   
    QStandardItem *parent = nullptr;
    if (insert == AtTopLevel)
    {
   
        parent = invisibleRootItem();
    }
    else if (insert == AsChild)
    {
   
        if (index.isValid())
        {
   
            parent = itemFromIndex(index);
        }
        else
            return 0;
    }
    return createNewIndex(parent, name, type);
}

QStandardItem *StandardTreeModel::createNewIndex(QStandardItem *root, const QString &name, items::ItemType type)
{
   
    QString str;
    switch (type) {
   
    case items::topAnd:
    case items::topOr:
        str = "顶事件";
        break;
    case items::midAnd:
    case items::midOr:
        str = "中间事件";
        break;
    case items::bottom:
        str = "底事件";
        break;
    default:
        break;
    }
    QStandardItem *nameItem = new QStandardItem(str);
    nameItem->setToolTip(name);
    nameItem->setData(type, ITEMTYPE);
    nameItem->setData(name, FAULTMSG);
    nameItem->setEditable(false);
    nameItem->setSelectable(true);
    root->appendRow(nameItem);
    return nameItem;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

2.使用QXmlStreamReader和QXmlStreamWriter来保存故障树


void StandardTreeModel::save(const QString &fileName)
{
   
    if (fileName.isEmpty())
        return;
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly|QIODevice::Text))
        return;
    QByteArray ary;
    QXmlStreamWriter writer(&ary);
    writer.setAutoFormatting(true);
    writer.writeStartDocument();
    writer.writeStartElement("Index");
    writer.writeAttribute("VERSION", "2.0");
    writeIndexAndChildren(&writer, invisibleRootItem());
    writer.writeEndElement();
    writer.writeEndDocument();
    file.write(ary);
    file.close();
}

void StandardTreeModel::writeIndexAndChildren(QXmlStreamWriter *writer, QStandardItem *root)
{
   
    if (root != invisibleRootItem()) {
   
        writer->writeStartElement("index");
        writer->writeAttribute(QString("type"), QString::number(root->data(ITEMTYPE).toInt()));
        writer->writeAttribute(QString("msg"), root->data(FAULTMSG).toString());
    }
    for (int row = 0; row < root->rowCount(); ++row)
        writeIndexAndChildren(writer, root->child(row, 0));
    if (root != invisibleRootItem())
        writer->writeEndElement();
}


void StandardTreeModel::load(const QString &fileName)
{
   
    if (fileName.isEmpty())
        return;
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly))
        return;
    QByteArray ary = file.readAll();
    clear();
    QStack<QStandardItem*> stack;
    stack.push(invisibleRootItem());
    QXmlStreamReader reader(ary);
    while (!reader.atEnd()) {
   
        reader.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/413222?site
推荐阅读
相关标签
  

闽ICP备14008679号