PowerMaster/source/alarmEventDataView.cpp

402 lines
12 KiB
C++
Raw Normal View History

#include "alarmEventDataView.h"
#include <QHeaderView>
#include <QVBoxLayout>
#include <QPainter>
#include <QTimer>
#include <QRandomGenerator>
///////------AlarmEventDataFilter-----
AlarmEventDataFilter::AlarmEventDataFilter()
{
m_type = -1;
m_status = -1;
}
bool AlarmEventDataFilter::matches(const EventData& event)
{
QDateTime eventTime = QDateTime::fromMSecsSinceEpoch(event.timestamp);
if(m_startTime.isValid() && eventTime < m_startTime)
return false;
if(m_endTime.isValid() && eventTime > m_endTime)
return false;
if(!m_station.isEmpty() && event.stationName != m_station)
return false;
if(!m_bay.isEmpty() && event.bayName != m_bay)
return false;
if(event.type != m_type)
return false;
if(!m_severity.isEmpty() && event.severity != m_severity)
return false;
if(!m_description.isEmpty() && event.description != m_description)
return false;
if(event.status != m_status)
return false;
return true;
}
void AlarmEventDataFilter::clear()
{
m_startTime = QDateTime();
m_endTime = QDateTime();
m_station.clear();
m_bay.clear();
m_type = -1;
m_severity.clear();
m_description.clear();
m_status = -1;
}
///////------AlarmEventDataModel-----
AlarmEventDataModel::AlarmEventDataModel(QObject* parent)
: QAbstractTableModel(parent)
,m_maxRealTimeEvents(5)
{
m_dataMode = Historical;
m_paginationInfo.entriesPerPage = 100;
m_paginationInfo.currentPage = 1;
m_paginationInfo.totalEntries = 0;
iniHeaderData();
//实时数据测试
m_simulatedDataTimer = new QTimer(this);
connect(m_simulatedDataTimer, &QTimer::timeout, this, &AlarmEventDataModel::onTimeoutSimulateData);
m_simulatedDataTimer->start(2000);
}
AlarmEventDataModel::~AlarmEventDataModel()
{}
QModelIndex AlarmEventDataModel::index(int row, int column, const QModelIndex& parent) const
{
if(!hasIndex(row, column, parent))
return QModelIndex();
if(column > m_headerData.count())
return QModelIndex();
return createIndex(row, column);
}
QVariant AlarmEventDataModel::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
return QVariant();
int row = index.row();
int col = index.column();
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
const EventData& event = m_displayEvents.at(row);
//EventData event = m_displayEvents[row];
switch (role)
{
case Qt::DisplayRole:
{
switch(col)
{
case Index:
return QString::number(globalRow + 1);
case ReceiveTime:
return QDateTime::fromMSecsSinceEpoch(event.timestamp).toString("yyyy-MM-dd hh:mm:ss");
case SOETime:
return QDateTime::fromMSecsSinceEpoch(event.timestamp).toString("yyyy-MM-dd hh:mm:ss");
case Station:
return event.stationName;
case Bay:
return event.bayName;
case Description:
return event.description;
case Type:
return event.type;
case Severity:
return event.severity;
case Status:
{
if(event.status < 3)
return QString("未确认");
else
return QString("已确认");
}
default:
return QVariant();
}
}
case Qt::ForegroundRole:
{
switch(col)
{
case Severity:
{
if(event.severity == "事故")
return QColor(255, 85, 0);
else if(event.severity == "异常")
return QColor(255, 170, 0);
else if(event.severity == "预警")
return QColor(0, 170, 255);
else if(event.severity == "告知")
return QColor(0, 170, 0);
else
return QColor(250, 250, 250);
}
case Status:
{
if(event.status < 3)
return QColor(0, 170, 255);
else
return QColor(0, 170, 0);
}
default:
return QColor(250, 250, 250);
}
}
case Qt::TextAlignmentRole:
return Qt::AlignCenter; //居中展示
default:
return QVariant();
}
}
QVariant AlarmEventDataModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
return m_headerData.at(section).text;
return QAbstractItemModel::headerData(section, orientation, role);
}
int AlarmEventDataModel::rowCount(const QModelIndex& parent) const
{
return m_displayEvents.count();
}
int AlarmEventDataModel::columnCount(const QModelIndex& parent) const
{
return m_headerData.isEmpty() ? 0 : m_headerData.count();
}
Qt::ItemFlags AlarmEventDataModel::flags(const QModelIndex& index) const
{
if(!index.isValid())
return Qt::NoItemFlags;
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
flags |= Qt::ItemIsEditable; //不可编辑
return flags;
}
void AlarmEventDataModel::iniHeaderData()
{
m_headerData.emplace_back(SectionData("序号", 90, Index));
m_headerData.emplace_back(SectionData("接收时间", 200, ReceiveTime));
m_headerData.emplace_back(SectionData("SOE时间", 200, SOETime));
m_headerData.emplace_back(SectionData("厂站", 200, Station));
m_headerData.emplace_back(SectionData("间隔", 200, Bay));
m_headerData.emplace_back(SectionData("信息", -1, Description));
m_headerData.emplace_back(SectionData("类型", 150, Type));
m_headerData.emplace_back(SectionData("等级", 150, Severity));
m_headerData.emplace_back(SectionData("确认状态", 150, Status));
m_headerData.emplace_back(SectionData("操作", 300, Operation));
}
void AlarmEventDataModel::setFilter(const AlarmEventDataFilter& filter)
{
m_currentFilter = filter;
}
void AlarmEventDataModel::applyFilter()
{}
void AlarmEventDataModel::refresh()
{}
void AlarmEventDataModel::updateCurPageData()
{
beginResetModel();
m_displayEvents.clear();
endResetModel();
}
void AlarmEventDataModel::updateTotalCount()
{}
int AlarmEventDataModel::findEventDataIndexById(const QString& eventId)
{
for(int i = 0; i < m_displayEvents.size(); i++)
{
if(m_displayEvents.at(i).id == eventId)
return i;
}
return -1;
}
void AlarmEventDataModel::updateEventData(int index, const EventData& updatedEvent)
{
if(index < 0 || index >= m_displayEvents.size())
return;
m_displayEvents[index] = updatedEvent;
//更新视图
QModelIndex modelIndex = createIndex(index, 0);
emit dataChanged(modelIndex, modelIndex);
}
void AlarmEventDataModel::onTimeoutSimulateData()
{
//模拟实时告警数据
static int id = 0, min = 0, max = 3;
int randomInt = min + QRandomGenerator::global()->bounded(min, max + 1);
QString strID = QString::number(++id);
//qDebug() << id << " " << strID;
EventData event;
event.id = strID;
event.name = QString("实时告警") + strID;
event.timestamp = QDateTime::currentMSecsSinceEpoch();
event.stationName = QString("厂站") + QString::number(randomInt);
event.bayName = QString("间隔") + QString::number(randomInt);
event.description = "";
event.type = 5;
QString severity = QString("预警");
if(randomInt == 0)
severity = QString("告知");
else if(randomInt == 1)
severity = QString("预警");
else if(randomInt == 2)
severity = QString("异常");
else if(randomInt == 3)
severity = QString("事故");
event.severity = severity;
event.status = 0;
onRealTimeEventReceived(event);
}
void AlarmEventDataModel::onRealTimeEventReceived(const EventData& event)
{
if(m_dataMode != RealTime)
return;
int index = findEventDataIndexById(event.id);
if(index >= 0)
{
updateEventData(index, event);
return;
}
beginResetModel();
//插入数据之前,先判断当前是否达到最大显示条目,达到的话删除最靠前(时间)的条目
if(m_displayEvents.size() >= m_maxRealTimeEvents)
m_displayEvents.removeLast();
//按照时间顺序排序(从小到大)
int insertPosition = 0;
for(; insertPosition < m_displayEvents.size(); ++insertPosition)
{
if(event.timestamp > m_displayEvents.at(insertPosition).timestamp)
break;
}
if(insertPosition < m_displayEvents.size())
m_displayEvents.insert(insertPosition, event);
else
m_displayEvents.append(event);
endResetModel();
}
///////------AlarmEventDataDelegate-----
AlarmEventDataDelegate::AlarmEventDataDelegate(QTableView* view, QObject* parent)
: QStyledItemDelegate(parent)
,m_tableView(view)
{}
AlarmEventDataDelegate::~AlarmEventDataDelegate()
{}
void AlarmEventDataDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
//根据行号设置交替颜色
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
if((index.row() + 1) % 2 == 0)
painter->fillRect(opt.rect, QColor(11, 26, 33, 100));
else
painter->fillRect(opt.rect, QColor(11, 26, 33, 0));
//绘制单元格边框(只绘制右边框,每行的最后一个单元格不绘制)
if(m_tableView)
{
painter->save();
QPen pen(QColor(60,60,60), 1, Qt::DotLine);
painter->setPen(pen);
if(index.column() != m_tableView->model()->columnCount() - 1)
{
//opt.rect.adjust(1, 0, 1, 0);
painter->drawLine(opt.rect.topRight(), opt.rect.bottomRight());
}
painter->restore();
}
//绘制默认内容
QStyledItemDelegate::paint(painter, option, index);
}
///////------AlarmEventDataView-----
AlarmEventDataView::AlarmEventDataView(QWidget* parent)
: QWidget(parent)
{
m_tableView = new QTableView(this);
m_tableView->verticalHeader()->setVisible(false);
m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_tableView->setShowGrid(false);
//m_tableView->setStyleSheet("QHeaderView{background-color: rgb(40, 40, 40);} QHeaderView::section{background-color:transparent;}");
m_tableModel = new AlarmEventDataModel(this);
m_tableView->setModel(m_tableModel);
//设置表头
const QVector<AlarmEventDataModel::SectionData> headerData = m_tableModel->headerData();
for(int i = 0; i < headerData.size(); i++)
{
if(headerData.at(i).width == -1)
m_tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
else
m_tableView->setColumnWidth(i, headerData.at(i).width);
}
m_delegate = new AlarmEventDataDelegate(m_tableView, this);
m_tableView->setItemDelegate(m_delegate);
m_vLayout = new QVBoxLayout(this);
m_vLayout->setSpacing(0);
m_vLayout->setContentsMargins(0, 0, 0, 0);
m_vLayout->addWidget(m_tableView);
this->setLayout(m_vLayout);
}
AlarmEventDataView::~AlarmEventDataView()
{}
void AlarmEventDataView::setModelMode(AlarmDataMode mode, int maxRealTimeEvents)
{
if(m_tableModel)
{
m_tableModel->setMode(mode);
if(mode == RealTime)
m_tableModel->setMaxRealTimeEvents(maxRealTimeEvents);
}
}