【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);
};

模型代码源文件:

#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;
}

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.readNext();
        if (reader.isStartElement()) {
   
            if (reader.name() == "index") {
   
                int type = reader.attributes
  • 50
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值