2025-09-18 15:50:18 +08:00
|
|
|
|
#include "alarmEventDataView.h"
|
2025-11-12 10:06:10 +08:00
|
|
|
|
#include "alarmEventDataService.h"
|
2025-09-18 15:50:18 +08:00
|
|
|
|
#include <QHeaderView>
|
|
|
|
|
|
#include <QVBoxLayout>
|
2025-09-19 17:45:52 +08:00
|
|
|
|
#include <QPainter>
|
2025-10-21 11:13:08 +08:00
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
#include <QRandomGenerator>
|
2025-10-23 19:05:48 +08:00
|
|
|
|
#include <QMouseEvent>
|
|
|
|
|
|
//#include <QApplication>
|
2025-09-18 15:50:18 +08:00
|
|
|
|
|
2025-09-19 17:45:52 +08:00
|
|
|
|
///////------AlarmEventDataModel-----
|
2025-10-28 16:39:23 +08:00
|
|
|
|
AlarmEventDataModel::AlarmEventDataModel(AlarmDataMode mode, QObject* parent)
|
2025-09-19 17:45:52 +08:00
|
|
|
|
: QAbstractTableModel(parent)
|
2025-10-28 16:39:23 +08:00
|
|
|
|
, m_dataMode(mode)
|
|
|
|
|
|
, m_maxRealTimeEvents(5)
|
2025-09-19 17:45:52 +08:00
|
|
|
|
{
|
2025-10-17 18:15:06 +08:00
|
|
|
|
m_paginationInfo.entriesPerPage = 100;
|
|
|
|
|
|
m_paginationInfo.currentPage = 1;
|
|
|
|
|
|
m_paginationInfo.totalEntries = 0;
|
2025-09-19 17:45:52 +08:00
|
|
|
|
iniHeaderData();
|
2025-10-21 11:13:08 +08:00
|
|
|
|
|
2025-11-12 10:06:10 +08:00
|
|
|
|
connect(AlarmEventDataService::instance(), &AlarmEventDataService::realTimeEventReceived, this, &AlarmEventDataModel::onRealTimeEventReceived);
|
|
|
|
|
|
connect(AlarmEventDataService::instance(), &AlarmEventDataService::historicalQueryData, this, &AlarmEventDataModel::onHistoricalEventsReceived);
|
2025-11-18 14:26:29 +08:00
|
|
|
|
connect(AlarmEventDataService::instance(), &AlarmEventDataService::historicalQueryError, this, &AlarmEventDataModel::onHistoricalQueryError);
|
2025-11-13 18:14:24 +08:00
|
|
|
|
|
2025-11-18 14:26:29 +08:00
|
|
|
|
if(m_dataMode == RealTime)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(int i = 0; i < m_maxRealTimeEvents; ++i)//创建几个“空事件”来初始化表格
|
|
|
|
|
|
{
|
|
|
|
|
|
EventData event;
|
|
|
|
|
|
event.id = ""; //空事件
|
|
|
|
|
|
event.timestamp = 0; //给一个初始值,后续的实际事件会根据时间排名,不给初始值的话这个时间值不确定
|
|
|
|
|
|
m_displayEvents.append(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AlarmEventDataService::instance()->start();
|
|
|
|
|
|
}
|
2025-11-13 18:14:24 +08:00
|
|
|
|
|
2025-10-21 11:13:08 +08:00
|
|
|
|
//实时数据测试
|
2025-11-25 11:54:16 +08:00
|
|
|
|
/*m_simulatedDataTimer = new QTimer(this);
|
2025-10-21 11:13:08 +08:00
|
|
|
|
connect(m_simulatedDataTimer, &QTimer::timeout, this, &AlarmEventDataModel::onTimeoutSimulateData);
|
2025-11-25 11:54:16 +08:00
|
|
|
|
m_simulatedDataTimer->start(3000);*/
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
{
|
2025-10-21 11:13:08 +08:00
|
|
|
|
if(!index.isValid())
|
2025-09-19 17:45:52 +08:00
|
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
|
|
|
|
int row = index.row();
|
|
|
|
|
|
int col = index.column();
|
2025-10-17 18:15:06 +08:00
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
2025-10-10 10:06:54 +08:00
|
|
|
|
const EventData& event = m_displayEvents.at(row);
|
2025-10-28 16:39:23 +08:00
|
|
|
|
if(event.id.isEmpty()) //无效事件
|
|
|
|
|
|
return QVariant();
|
2025-10-10 10:06:54 +08:00
|
|
|
|
//EventData event = m_displayEvents[row];
|
2025-09-19 17:45:52 +08:00
|
|
|
|
|
|
|
|
|
|
switch (role)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Qt::DisplayRole:
|
|
|
|
|
|
{
|
2025-10-10 10:06:54 +08:00
|
|
|
|
switch(col)
|
|
|
|
|
|
{
|
2025-10-21 11:13:08 +08:00
|
|
|
|
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();
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-10 10:06:54 +08:00
|
|
|
|
case Qt::ForegroundRole:
|
|
|
|
|
|
{
|
2025-10-21 11:13:08 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2025-10-10 10:06:54 +08:00
|
|
|
|
}
|
2025-09-19 17:45:52 +08:00
|
|
|
|
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
|
|
|
|
|
|
{
|
2025-10-10 10:06:54 +08:00
|
|
|
|
return m_displayEvents.count();
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
{
|
2025-10-10 10:06:54 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("序号", 90, Index));
|
2025-10-21 11:13:08 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("接收时间", 200, ReceiveTime));
|
|
|
|
|
|
m_headerData.emplace_back(SectionData("SOE时间", 200, SOETime));
|
2025-10-10 10:06:54 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("厂站", 200, Station));
|
|
|
|
|
|
m_headerData.emplace_back(SectionData("间隔", 200, Bay));
|
|
|
|
|
|
m_headerData.emplace_back(SectionData("信息", -1, Description));
|
2025-11-17 10:13:02 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("类型", 160, Type));
|
2025-12-01 09:55:07 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("级别", 160, Severity));
|
2025-10-10 10:06:54 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("确认状态", 150, Status));
|
2025-11-17 10:13:02 +08:00
|
|
|
|
m_headerData.emplace_back(SectionData("操作", 180, Operation));
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 11:54:16 +08:00
|
|
|
|
void AlarmEventDataModel::setMode(AlarmDataMode mode)
|
2025-10-28 16:39:23 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(m_dataMode == mode)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
m_dataMode = mode;
|
2025-11-25 11:54:16 +08:00
|
|
|
|
/*if(mode == Historical_All)
|
2025-10-28 16:39:23 +08:00
|
|
|
|
{}
|
2025-11-25 11:54:16 +08:00
|
|
|
|
else if(mode == Historical_Unconfirmed)
|
|
|
|
|
|
{}*/
|
|
|
|
|
|
}
|
2025-10-28 16:39:23 +08:00
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::setMaxRealTimeEvents(int count)
|
|
|
|
|
|
{
|
2025-11-12 16:30:17 +08:00
|
|
|
|
if(m_dataMode == RealTime) //实时列表初始化表格
|
2025-10-28 16:39:23 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(m_maxRealTimeEvents == count)
|
|
|
|
|
|
return;
|
|
|
|
|
|
else if(m_maxRealTimeEvents < count)
|
|
|
|
|
|
{
|
|
|
|
|
|
int DValue = count - m_maxRealTimeEvents;
|
|
|
|
|
|
for(int i = 0; i < DValue; ++i)
|
|
|
|
|
|
m_displayEvents.removeLast();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(m_maxRealTimeEvents > count)
|
|
|
|
|
|
{
|
|
|
|
|
|
int DValue = m_maxRealTimeEvents - count;
|
|
|
|
|
|
for(int i = 0; i < DValue; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
EventData event;
|
|
|
|
|
|
event.id = ""; //空事件
|
|
|
|
|
|
m_displayEvents.append(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_maxRealTimeEvents = count;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
void AlarmEventDataModel::setFilter(const AlarmEventDataFilter& filter)
|
|
|
|
|
|
{
|
2025-11-25 11:54:16 +08:00
|
|
|
|
if(m_dataMode == RealTime)
|
2025-11-18 14:26:29 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
m_currentFilter = filter;
|
2025-10-27 17:43:39 +08:00
|
|
|
|
refresh();
|
2025-10-17 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::applyFilter()
|
2025-10-27 17:43:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
m_filteredEvents.clear();
|
|
|
|
|
|
|
|
|
|
|
|
if(m_allEvents.size() > 0)
|
|
|
|
|
|
m_filteredEvents = m_currentFilter.apply(m_allEvents);
|
|
|
|
|
|
}
|
2025-10-17 18:15:06 +08:00
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::refresh()
|
2025-09-24 12:10:51 +08:00
|
|
|
|
{
|
2025-11-25 11:54:16 +08:00
|
|
|
|
//通过服务获取当前时间段的所有对应类型(所有or确认or未确认)事件-m_allEvents
|
|
|
|
|
|
if(m_dataMode == RealTime)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
AlarmEventDataService::instance()->queryHistoricalEvents(m_currentFilter.beginTime(), m_currentFilter.endTime(), m_currentFilter.confirmStatus());
|
2025-09-24 12:10:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-24 17:28:14 +08:00
|
|
|
|
void AlarmEventDataModel::updatePaginationInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_paginationInfo.totalEntries = m_filteredEvents.size();
|
|
|
|
|
|
m_paginationInfo.totalPages = qCeil(static_cast<qreal>(m_paginationInfo.totalEntries) / m_paginationInfo.entriesPerPage);
|
|
|
|
|
|
if(m_paginationInfo.totalPages == 0)
|
|
|
|
|
|
m_paginationInfo.currentPage = 1;
|
|
|
|
|
|
else if(m_paginationInfo.currentPage > m_paginationInfo.totalPages)
|
|
|
|
|
|
m_paginationInfo.currentPage = m_paginationInfo.totalPages;
|
|
|
|
|
|
}
|
2025-09-24 12:10:51 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
int AlarmEventDataModel::findEventDataIndexById(const QString& eventId)
|
2025-10-13 17:31:50 +08:00
|
|
|
|
{
|
2025-10-17 18:15:06 +08:00
|
|
|
|
for(int i = 0; i < m_displayEvents.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_displayEvents.at(i).id == eventId)
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
2025-10-13 17:31:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
void AlarmEventDataModel::updateEventData(int index, const EventData& updatedEvent)
|
2025-10-13 17:31:50 +08:00
|
|
|
|
{
|
2025-10-17 18:15:06 +08:00
|
|
|
|
if(index < 0 || index >= m_displayEvents.size())
|
|
|
|
|
|
return;
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
m_displayEvents[index] = updatedEvent;
|
|
|
|
|
|
//更新视图
|
|
|
|
|
|
QModelIndex modelIndex = createIndex(index, 0);
|
|
|
|
|
|
emit dataChanged(modelIndex, modelIndex);
|
|
|
|
|
|
}
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-24 17:28:14 +08:00
|
|
|
|
void AlarmEventDataModel::updateCurPageData()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_displayEvents.clear();
|
|
|
|
|
|
int startIndex = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage;
|
|
|
|
|
|
int endIndex = qMin(startIndex + m_paginationInfo.entriesPerPage, m_filteredEvents.size());
|
|
|
|
|
|
|
|
|
|
|
|
beginResetModel();
|
|
|
|
|
|
|
|
|
|
|
|
if(startIndex < m_filteredEvents.size())
|
|
|
|
|
|
m_displayEvents = m_filteredEvents.mid(startIndex, endIndex - startIndex);
|
|
|
|
|
|
|
|
|
|
|
|
endResetModel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-21 11:13:08 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
void AlarmEventDataModel::onRealTimeEventReceived(const EventData& event)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_dataMode != RealTime)
|
|
|
|
|
|
return;
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
int index = findEventDataIndexById(event.id);
|
|
|
|
|
|
if(index >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
updateEventData(index, event);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
beginResetModel();
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
//插入数据之前,先判断当前是否达到最大显示条目,达到的话删除最靠前(时间)的条目
|
|
|
|
|
|
if(m_displayEvents.size() >= m_maxRealTimeEvents)
|
|
|
|
|
|
m_displayEvents.removeLast();
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-28 16:39:23 +08:00
|
|
|
|
//按照时间顺序排序(从后到前)
|
2025-10-17 18:15:06 +08:00
|
|
|
|
int insertPosition = 0;
|
|
|
|
|
|
for(; insertPosition < m_displayEvents.size(); ++insertPosition)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(event.timestamp > m_displayEvents.at(insertPosition).timestamp)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
if(insertPosition < m_displayEvents.size())
|
|
|
|
|
|
m_displayEvents.insert(insertPosition, event);
|
|
|
|
|
|
else
|
|
|
|
|
|
m_displayEvents.append(event);
|
2025-10-13 17:31:50 +08:00
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
endResetModel();
|
2025-10-29 17:38:57 +08:00
|
|
|
|
|
|
|
|
|
|
emit receivedNewAlarm(event);
|
2025-10-13 17:31:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-12 10:06:10 +08:00
|
|
|
|
void AlarmEventDataModel::onHistoricalEventsReceived(const QList<EventData>& events)
|
|
|
|
|
|
{
|
2025-11-18 14:26:29 +08:00
|
|
|
|
m_allEvents.clear();
|
|
|
|
|
|
m_allEvents = events;
|
|
|
|
|
|
|
|
|
|
|
|
//过滤事件(时间区间作为服务请求参数,其它过滤在本地完成)-m_filteredEvents
|
|
|
|
|
|
applyFilter();
|
|
|
|
|
|
//更新页码数据
|
|
|
|
|
|
updatePaginationInfo();
|
|
|
|
|
|
//根据页码刷新当前页面数据()-m_displayEvents
|
|
|
|
|
|
updateCurPageData();
|
|
|
|
|
|
|
|
|
|
|
|
emit syncDataStatus(m_paginationInfo);
|
|
|
|
|
|
}
|
2025-11-12 10:06:10 +08:00
|
|
|
|
|
2025-11-18 14:26:29 +08:00
|
|
|
|
void AlarmEventDataModel::onHistoricalQueryError(const QString& error)
|
|
|
|
|
|
{
|
|
|
|
|
|
emit loadDataError(error);
|
2025-11-12 10:06:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-28 16:39:23 +08:00
|
|
|
|
bool AlarmEventDataModel::setCurrentPage(int page)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage != page && page > 0 && page <= m_paginationInfo.totalPages)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_paginationInfo.currentPage = page;
|
|
|
|
|
|
updateCurPageData();
|
2025-12-01 09:55:07 +08:00
|
|
|
|
emit syncDataStatus(m_paginationInfo);
|
2025-10-28 16:39:23 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-01 09:55:07 +08:00
|
|
|
|
int AlarmEventDataModel::currentPage() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_paginationInfo.currentPage;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-28 16:39:23 +08:00
|
|
|
|
void AlarmEventDataModel::previousPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage == 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
int page = m_paginationInfo.currentPage;
|
|
|
|
|
|
setCurrentPage(--page);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::nextPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage == m_paginationInfo.totalPages)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
int page = m_paginationInfo.currentPage;
|
|
|
|
|
|
setCurrentPage(++page);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::firstPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage == 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataModel::lastPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage == m_paginationInfo.totalPages)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(m_paginationInfo.totalPages);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 18:15:06 +08:00
|
|
|
|
|
2025-09-19 17:45:52 +08:00
|
|
|
|
///////------AlarmEventDataDelegate-----
|
|
|
|
|
|
AlarmEventDataDelegate::AlarmEventDataDelegate(QTableView* view, QObject* parent)
|
|
|
|
|
|
: QStyledItemDelegate(parent)
|
|
|
|
|
|
,m_tableView(view)
|
2025-10-23 16:54:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
m_btnConfirm.text = QString("确 认");
|
|
|
|
|
|
m_btnConfirm.textColor = QColor(34, 177, 16);
|
|
|
|
|
|
m_btnConfirm.borderColor = QColor(34, 177, 16);
|
|
|
|
|
|
m_btnConfirm.borderWidth = 1;
|
|
|
|
|
|
m_btnConfirm.borderRaius = 2;
|
|
|
|
|
|
m_btnConfirm.normalBgColor = Qt::transparent;
|
|
|
|
|
|
m_btnConfirm.hoverBgColor = QColor(34, 177, 16, 80);
|
|
|
|
|
|
m_btnConfirm.pressedBgColor = Qt::transparent;
|
|
|
|
|
|
|
|
|
|
|
|
m_btnReplay.text = QString("回 放");
|
|
|
|
|
|
m_btnReplay.textColor = QColor(86, 156, 214);
|
|
|
|
|
|
m_btnReplay.borderColor = QColor(86, 156, 214);
|
|
|
|
|
|
m_btnReplay.borderWidth = 1;
|
|
|
|
|
|
m_btnReplay.borderRaius = 2;
|
|
|
|
|
|
m_btnReplay.normalBgColor = Qt::transparent;
|
|
|
|
|
|
m_btnReplay.hoverBgColor = QColor(86, 156, 214, 80);
|
|
|
|
|
|
m_btnReplay.pressedBgColor = Qt::transparent;
|
|
|
|
|
|
}
|
2025-09-19 17:45:52 +08:00
|
|
|
|
|
|
|
|
|
|
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)
|
2025-10-21 11:13:08 +08:00
|
|
|
|
painter->fillRect(opt.rect, QColor(11, 26, 33, 100));
|
2025-09-19 17:45:52 +08:00
|
|
|
|
else
|
|
|
|
|
|
painter->fillRect(opt.rect, QColor(11, 26, 33, 0));
|
|
|
|
|
|
|
|
|
|
|
|
if(m_tableView)
|
|
|
|
|
|
{
|
2025-10-23 16:54:59 +08:00
|
|
|
|
//绘制单元格边框(只绘制右边框,每行的最后一个单元格不绘制)
|
2025-09-19 17:45:52 +08:00
|
|
|
|
painter->save();
|
2025-10-21 14:50:58 +08:00
|
|
|
|
QPen pen(QColor(60,60,60), 1, Qt::DotLine);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
painter->setPen(pen);
|
|
|
|
|
|
if(index.column() != m_tableView->model()->columnCount() - 1)
|
2025-10-21 14:50:58 +08:00
|
|
|
|
{
|
|
|
|
|
|
//opt.rect.adjust(1, 0, 1, 0);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
painter->drawLine(opt.rect.topRight(), opt.rect.bottomRight());
|
2025-10-21 14:50:58 +08:00
|
|
|
|
}
|
2025-09-19 17:45:52 +08:00
|
|
|
|
painter->restore();
|
2025-10-23 16:54:59 +08:00
|
|
|
|
|
|
|
|
|
|
//绘制操作按钮
|
2025-10-28 16:39:23 +08:00
|
|
|
|
QModelIndex numIndex = m_tableView->model()->index(index.row(), 0);
|
|
|
|
|
|
QString number = numIndex.data(Qt::DisplayRole).toString();
|
|
|
|
|
|
if(!number.isEmpty() && index.column() == m_tableView->model()->columnCount() - 1)
|
2025-10-23 16:54:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
int nMarginH = 10;
|
|
|
|
|
|
int nMarginV = 5;
|
|
|
|
|
|
int nSpacing = 10;
|
|
|
|
|
|
int nBtnWidth = (opt.rect.width() - nMarginH * 2 - nSpacing) * 0.5;
|
|
|
|
|
|
int nBtnHeight = opt.rect.height() - nMarginV * 2;
|
|
|
|
|
|
|
|
|
|
|
|
/*QStyleOptionButton btnConfirm;
|
|
|
|
|
|
btnConfirm.text = QString("确 认");
|
|
|
|
|
|
btnConfirm.rect = QRect(opt.rect.left() + nMarginH, opt.rect.top() + nMarginV, nBtnWidth, nBtnHeight);
|
|
|
|
|
|
btnConfirm.state |= QStyle::State_Enabled;
|
|
|
|
|
|
QStyleOptionButton btnReplay;
|
|
|
|
|
|
btnReplay.text = QString("回 放");
|
|
|
|
|
|
btnReplay.rect = QRect(btnConfirm.rect.right() + nSpacing, opt.rect.top() + nMarginV, nBtnWidth, nBtnHeight);
|
|
|
|
|
|
btnReplay.state |= QStyle::State_Enabled;
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制按钮
|
|
|
|
|
|
QApplication::style()->drawControl(QStyle::CE_PushButton, &btnConfirm, painter);
|
|
|
|
|
|
QApplication::style()->drawControl(QStyle::CE_PushButtonLabel, &btnReplay, painter);*/
|
|
|
|
|
|
|
|
|
|
|
|
const_cast<AlarmEventDataDelegate*>(this)->m_btnConfirm.rect = QRect(opt.rect.left() + nMarginH, opt.rect.top() + nMarginV, nBtnWidth, nBtnHeight);
|
|
|
|
|
|
const_cast<AlarmEventDataDelegate*>(this)->m_btnReplay.rect = QRect(m_btnConfirm.rect.right() + nSpacing, opt.rect.top() + nMarginV, nBtnWidth, nBtnHeight);
|
|
|
|
|
|
|
|
|
|
|
|
painter->save();
|
|
|
|
|
|
|
|
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
|
|
//绘制‘确认’按钮
|
|
|
|
|
|
QPen rectPen;
|
|
|
|
|
|
rectPen.setColor(m_btnConfirm.borderColor);
|
|
|
|
|
|
rectPen.setWidth(m_btnConfirm.borderWidth);
|
|
|
|
|
|
painter->setPen(rectPen);
|
2025-10-23 19:05:48 +08:00
|
|
|
|
QColor brushColor = m_btnConfirm.normalBgColor;
|
|
|
|
|
|
bool isHover = opt.state.testFlag(QStyle::State_MouseOver) && m_btnConfirm.rect.contains(m_mousePositon); //opt.state.testFlag(QStyle::State_MouseOver)表示鼠标是否悬停在该视图项(即单元格)上
|
|
|
|
|
|
//bool isPressed = opt.state.testFlag(QStyle::State_Sunken) && m_btnConfirm.rect.contains(m_mousePositon);//opt.state.testFlag(QStyle::State_Sunken)表示鼠标是否在该视图项(即单元格)上按下
|
|
|
|
|
|
bool isPressed = m_buttonColumnIsPress && m_btnConfirm.rect.contains(m_mousePositon); //opt.state.testFlag(QStyle::State_Sunken)总是为false且未找到原因
|
|
|
|
|
|
//注意判断顺序,一定要先先判断press
|
|
|
|
|
|
if(isPressed)
|
|
|
|
|
|
brushColor = m_btnConfirm.pressedBgColor;
|
|
|
|
|
|
else if(isHover)
|
|
|
|
|
|
brushColor = m_btnConfirm.hoverBgColor;
|
|
|
|
|
|
painter->setBrush(brushColor);
|
2025-10-23 16:54:59 +08:00
|
|
|
|
painter->drawRoundedRect(m_btnConfirm.rect, m_btnConfirm.borderRaius, m_btnConfirm.borderRaius);
|
|
|
|
|
|
painter->setPen(m_btnConfirm.textColor);
|
|
|
|
|
|
painter->drawText(m_btnConfirm.rect, Qt::AlignCenter, m_btnConfirm.text);
|
|
|
|
|
|
//绘制‘回放’按钮
|
|
|
|
|
|
rectPen.setColor(m_btnReplay.borderColor);
|
|
|
|
|
|
rectPen.setWidth(m_btnReplay.borderWidth);
|
|
|
|
|
|
painter->setPen(rectPen);
|
2025-10-23 19:05:48 +08:00
|
|
|
|
brushColor = m_btnReplay.normalBgColor;
|
|
|
|
|
|
isHover = opt.state.testFlag(QStyle::State_MouseOver) && m_btnReplay.rect.contains(m_mousePositon);
|
|
|
|
|
|
//isPressed = opt.state.testFlag(QStyle::State_Sunken) && isHover;
|
|
|
|
|
|
isPressed = m_buttonColumnIsPress && m_btnReplay.rect.contains(m_mousePositon);
|
|
|
|
|
|
if(isPressed)
|
|
|
|
|
|
brushColor = m_btnReplay.pressedBgColor;
|
|
|
|
|
|
else if(isHover)
|
|
|
|
|
|
brushColor = m_btnReplay.hoverBgColor;
|
|
|
|
|
|
painter->setBrush(brushColor);
|
2025-10-23 16:54:59 +08:00
|
|
|
|
painter->drawRoundedRect(m_btnReplay.rect, m_btnReplay.borderRaius, m_btnReplay.borderRaius);
|
|
|
|
|
|
painter->setPen(m_btnReplay.textColor);
|
|
|
|
|
|
painter->drawText(m_btnReplay.rect, Qt::AlignCenter, m_btnReplay.text);
|
|
|
|
|
|
|
|
|
|
|
|
painter->restore();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(opt.state.testFlag(QStyle::State_Selected))
|
|
|
|
|
|
{
|
|
|
|
|
|
//方法1:移除选中状态,防止选中改变文字颜色
|
|
|
|
|
|
//opt.state &= ~QStyle::State_Selected;
|
|
|
|
|
|
|
|
|
|
|
|
//方法2
|
|
|
|
|
|
QColor originalTextColor = opt.palette.color(QPalette::Text);
|
|
|
|
|
|
opt.palette.setColor(QPalette::HighlightedText, originalTextColor);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//绘制默认内容
|
2025-10-23 16:54:59 +08:00
|
|
|
|
QStyledItemDelegate::paint(painter, opt, index);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AlarmEventDataDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
|
|
|
|
|
|
{
|
2025-10-23 19:05:48 +08:00
|
|
|
|
if(m_tableView && index.column() == m_tableView->model()->columnCount() - 1) //只处理操作按钮所在列的事件
|
|
|
|
|
|
{
|
|
|
|
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
|
|
|
|
|
m_mousePositon = mouseEvent->pos();
|
|
|
|
|
|
m_buttonColumnIsPress = false;
|
|
|
|
|
|
|
|
|
|
|
|
if(mouseEvent->type() == QEvent::MouseMove)
|
|
|
|
|
|
{
|
|
|
|
|
|
emit m_tableView->model()->dataChanged(index, index); //触发重绘
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QEvent::MouseButtonPress)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_buttonColumnIsPress = true;
|
|
|
|
|
|
emit m_tableView->model()->dataChanged(index, index); //触发重绘
|
|
|
|
|
|
//qDebug() << option.state.testFlag(QStyle::State_Sunken);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QEvent::MouseButtonRelease)
|
|
|
|
|
|
{
|
|
|
|
|
|
emit m_tableView->model()->dataChanged(index, index); //触发重绘
|
2025-10-23 20:21:32 +08:00
|
|
|
|
if(m_btnConfirm.rect.contains(m_mousePositon))
|
|
|
|
|
|
emit confirmBtnClicked(index);
|
|
|
|
|
|
else if(m_btnReplay.rect.contains(m_mousePositon))
|
|
|
|
|
|
emit replayBtnClicked(index);
|
2025-10-23 19:05:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-23 16:54:59 +08:00
|
|
|
|
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////------AlarmEventDataView-----
|
2025-10-28 16:39:23 +08:00
|
|
|
|
AlarmEventDataView::AlarmEventDataView(AlarmDataMode mode, QWidget* parent)
|
2025-09-18 15:50:18 +08:00
|
|
|
|
: QWidget(parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_tableView = new QTableView(this);
|
|
|
|
|
|
m_tableView->verticalHeader()->setVisible(false);
|
|
|
|
|
|
m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
2025-10-23 16:54:59 +08:00
|
|
|
|
//m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
2025-09-18 15:50:18 +08:00
|
|
|
|
m_tableView->setShowGrid(false);
|
|
|
|
|
|
//m_tableView->setStyleSheet("QHeaderView{background-color: rgb(40, 40, 40);} QHeaderView::section{background-color:transparent;}");
|
|
|
|
|
|
|
2025-10-28 16:39:23 +08:00
|
|
|
|
m_tableModel = new AlarmEventDataModel(mode, this);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
m_tableView->setModel(m_tableModel);
|
2025-10-10 10:06:54 +08:00
|
|
|
|
//设置表头
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
2025-09-19 17:45:52 +08:00
|
|
|
|
|
|
|
|
|
|
m_delegate = new AlarmEventDataDelegate(m_tableView, this);
|
2025-10-23 20:21:32 +08:00
|
|
|
|
connect(m_delegate, &AlarmEventDataDelegate::confirmBtnClicked, this, &AlarmEventDataView::onBtnClicked_Confirm);
|
|
|
|
|
|
connect(m_delegate, &AlarmEventDataDelegate::replayBtnClicked, this, &AlarmEventDataView::onBtnClicked_Replay);
|
2025-09-19 17:45:52 +08:00
|
|
|
|
m_tableView->setItemDelegate(m_delegate);
|
|
|
|
|
|
|
2025-09-18 15:50:18 +08:00
|
|
|
|
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()
|
|
|
|
|
|
{}
|
2025-10-21 11:13:08 +08:00
|
|
|
|
|
2025-10-28 16:39:23 +08:00
|
|
|
|
/*void AlarmEventDataView::setModelMode(AlarmDataMode mode, int maxRealTimeEvents)
|
2025-10-21 11:13:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(m_tableModel)
|
2025-10-21 14:50:58 +08:00
|
|
|
|
{
|
2025-10-21 11:13:08 +08:00
|
|
|
|
m_tableModel->setMode(mode);
|
2025-10-21 14:50:58 +08:00
|
|
|
|
if(mode == RealTime)
|
|
|
|
|
|
m_tableModel->setMaxRealTimeEvents(maxRealTimeEvents);
|
|
|
|
|
|
}
|
2025-10-28 16:39:23 +08:00
|
|
|
|
}*/
|
2025-10-23 20:21:32 +08:00
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataView::onBtnClicked_Confirm(const QModelIndex& index)
|
|
|
|
|
|
{
|
|
|
|
|
|
qDebug() << QString("confirmBtnClicked, row: %1").arg(index.row());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlarmEventDataView::onBtnClicked_Replay(const QModelIndex& index)
|
|
|
|
|
|
{
|
|
|
|
|
|
qDebug() << QString("replayBtnClicked, row: %1").arg(index.row());
|
|
|
|
|
|
}
|