add monitor item display

This commit is contained in:
baiYue 2025-12-03 18:27:49 +08:00
parent 258c8b88a0
commit 993c9b8e3a
15 changed files with 594 additions and 233 deletions

View File

@ -1108,7 +1108,8 @@ struct monitorItemAttributeInfo //单个监控item属性
}; };
enum class monitorItemState{ //监控item的状态 enum class monitorItemState{ //监控item的状态
Closing = 0, //合闸 Normal = 0, //正常
Closing, //合闸
Opening, //分闸 Opening, //分闸
AccidentTrip, //事故跳闸 AccidentTrip, //事故跳闸
StatusFault, //状态故障 StatusFault, //状态故障
@ -1118,7 +1119,6 @@ enum class monitorItemState{ //监控item的状态
Running, //运行 Running, //运行
ShutDown, //停运 ShutDown, //停运
Alarm, //告警 Alarm, //告警
Normal, //正常
LineBreak, //断线 LineBreak, //断线
MeasureMentOutLimit //量测越限 MeasureMentOutLimit //量测越限
}; };
@ -1138,39 +1138,37 @@ struct monitorItemDisplayInfo //监控模式显示信息
struct monitorItemTypeStruct //监控设备类型 struct monitorItemTypeStruct //监控设备类型
{ {
QString sTag; //英文 QString sTag;
QString sName; QString sName;
bool operator<(const monitorItemTypeStruct& other) const { bool isValid() const {
if (sTag != other.sTag) return !sTag.isEmpty() && !sName.isEmpty();
return sTag < other.sTag;
return sName < other.sName;
} }
bool notEmpty(){ bool operator==(const monitorItemTypeStruct& other) const {
if(!sTag.isEmpty() && !sName.isEmpty()) return sTag == other.sTag && sName == other.sName;
return true; }
else
return false; bool operator<(const monitorItemTypeStruct& other) const {
return sTag < other.sTag || (sTag == other.sTag && sName < other.sName);
} }
}; };
struct monitorItemStateStruct //监控设备状态 struct monitorItemStateStruct //监控设备状态
{ {
monitorItemState eState; QString sState;
QString sState; //状态(中文) monitorItemState eState;
bool operator<(const monitorItemStateStruct& other) const { bool isValid() const {
if (eState != other.eState) return !sState.isEmpty();
return eState < other.eState;
return sState < other.sState;
} }
bool notEmpty(){ bool operator==(const monitorItemStateStruct& other) const {
if(!sState.isEmpty()) return sState == other.sState && eState == other.eState;
return true; }
else
return false; bool operator<(const monitorItemStateStruct& other) const {
return sState < other.sState || (sState == other.sState && eState < other.eState);
} }
}; };

View File

@ -19,11 +19,13 @@ public:
void move(const QPointF&) override; void move(const QPointF&) override;
virtual void addSvgItem(ElectricSvgItem* item); virtual void addSvgItem(ElectricSvgItem* item);
virtual void updateMapSvg(QMap<QString,QByteArray> map); //工程模property不含图片额外存储 virtual void updateMapSvg(QMap<QString,QByteArray> map); //工程模property不含图片额外存储
virtual void setMonitorDisplayInfo(QMap<monitorItemStateStruct,monitorItemDisplayInfo> info) override; //将显示数据更新到子item中
protected: protected:
virtual QPainterPath shape() override; virtual QPainterPath shape() override;
virtual void editShape(int, const QPointF&) override; virtual void editShape(int, const QPointF&) override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
protected:
virtual void updateCurState(monitorItemState e) override;
protected: protected:
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect QRectF m_lastBoudingRect; //记录上一时刻的boundingRect
QMap<QString,QByteArray> m_mapSvg; QMap<QString,QByteArray> m_mapSvg;

View File

@ -18,13 +18,15 @@ public:
virtual void loadSvg(){}; virtual void loadSvg(){};
virtual void loadSvg(QByteArray); //第二种load直接加载图片 virtual void loadSvg(QByteArray); //第二种load直接加载图片
virtual void updateMapSvg(QMap<QString,QByteArray> map); virtual void updateMapSvg(QMap<QString,QByteArray> map);
virtual void updateCurState(monitorItemState e) override;
protected: protected:
virtual QPainterPath shape() override; virtual QPainterPath shape() override;
virtual void editShape(int, const QPointF&) override; virtual void editShape(int, const QPointF&) override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
protected: protected:
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect QRectF m_lastBoudingRect; //记录上一时刻的boundingRect
QSvgRenderer* m_pRender; QSvgRenderer* m_pRender; //默认
QSvgRenderer* m_pCustomRender; //定制
QMap<QString,QByteArray> m_mapSvg; QMap<QString,QByteArray> m_mapSvg;
QByteArray _tempSvg; //保存直接加载的svg数据 QByteArray _tempSvg; //保存直接加载的svg数据
}; };

View File

@ -177,7 +177,7 @@ class GraphicsBaseItem :public QObject, public AbstractShapeType<QGraphicsItem>
virtual GraphicsBaseItem* clone() const = 0; virtual GraphicsBaseItem* clone() const = 0;
public: public:
virtual int addPort(PortState typ,QPointF vec,QString id = "",HandleType hType = T_lineInOut,PortPos pos = P_top,double dXPercent = 0,double dYPercent = 0); //新建,返回-1失败 int addPort(PortState typ,QPointF vec,QString id = "",HandleType hType = T_lineInOut,PortPos pos = P_top,double dXPercent = 0,double dYPercent = 0); //新建,返回-1失败
virtual void movePort(QString id,QPointF vec); //移动可动点 virtual void movePort(QString id,QPointF vec); //移动可动点
virtual void setEntity(PowerEntity*); //设置当前图元的拓扑数据 virtual void setEntity(PowerEntity*); //设置当前图元的拓扑数据
virtual PowerEntity* entity(); virtual PowerEntity* entity();
@ -578,6 +578,15 @@ public:
virtual void updateTerPos(); //ct,pt等item大小变动后重新计算端点位置 virtual void updateTerPos(); //ct,pt等item大小变动后重新计算端点位置
virtual void setCurMonitorState(monitorItemState sta) {_curMonitorState = sta;} //设置当前运行时模式 virtual void setCurMonitorState(monitorItemState sta) {_curMonitorState = sta;} //设置当前运行时模式
virtual void setMonitorDisplayInfo(QMap<monitorItemStateStruct,monitorItemDisplayInfo> info){_displaySetting = info;} virtual void setMonitorDisplayInfo(QMap<monitorItemStateStruct,monitorItemDisplayInfo> info){_displaySetting = info;}
virtual void updateCurState(monitorItemState e){ //更新当前显示模式(运行时)
if(ifStateExist(e)){
_curMonitorState = e;
auto info = getInfoByState(e);
_curMonitorStateColor = QColor(info.sColor);
_curMonitorStateSvg = info.bytPicture;
_curMonitorStateEnable = info.bEnable;
}
}
protected: protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&) override; virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&) override;
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override;
@ -586,6 +595,23 @@ signals:
void ifExist(QUuid id,const QString&,int type,GraphicsProjectModelItem*); void ifExist(QUuid id,const QString&,int type,GraphicsProjectModelItem*);
public slots: public slots:
void onEditNameFinish(const QString&); void onEditNameFinish(const QString&);
protected:
bool ifStateExist(monitorItemState sta){ //判断指定状态存在
for(auto iter = _displaySetting.begin();iter != _displaySetting.end();++iter){
if(iter.key().eState == sta){
return true;
}
}
return false;
}
monitorItemDisplayInfo getInfoByState(monitorItemState sta){ //返回指定状态设置值
for(auto iter = _displaySetting.begin();iter != _displaySetting.end();++iter){
if(iter.key().eState == sta){
return iter.value();
}
}
return monitorItemDisplayInfo();
}
protected: protected:
ItemState m_state; ItemState m_state;
QPointF m_beginConnectPoint; QPointF m_beginConnectPoint;
@ -593,6 +619,9 @@ protected:
int _lastPort; //最后触碰的port int _lastPort; //最后触碰的port
QString _modelName; //当前图元使用的模型名用来在model中检索属性信息 QString _modelName; //当前图元使用的模型名用来在model中检索属性信息
monitorItemState _curMonitorState; //当前运行时模式 monitorItemState _curMonitorState; //当前运行时模式
QColor _curMonitorStateColor;
QByteArray _curMonitorStateSvg;
bool _curMonitorStateEnable;
QMap<monitorItemStateStruct,monitorItemDisplayInfo> _displaySetting; //显示设置 QMap<monitorItemStateStruct,monitorItemDisplayInfo> _displaySetting; //显示设置
}; };

View File

@ -26,15 +26,22 @@ public slots:
void onIconSelectClicked(); void onIconSelectClicked();
void onCheckboxToggled(bool); void onCheckboxToggled(bool);
void onTypeChanged(const QString&); void onDeviceComboBoxChanged(const QString&);
void onStateChanged(const QString&); void onStateComboBoxChanged(const QString&);
private: private:
void loadSetting(monitorItemTypeStruct type,monitorItemStateStruct state); //载入设定到界面 void loadSetting(monitorItemTypeStruct type, monitorItemStateStruct state);
void saveSetting(monitorItemTypeStruct type,monitorItemStateStruct state); bool saveCurrentSettingsWithIcon();
void loadFirstStateSafely();
void updatePreview(); //预览更新 // 图片处理
void clearStateDisplay(); void clearStateDisplay();
void updateIconDisplay(const QByteArray& svgData);
void clearIconDisplay();
bool validateSvgData(const QByteArray& svgData) const;
// 辅助方法
bool validateCurrentDeviceState() const;
private: private:
Ui::monitorDisplaySettingDlg *ui; Ui::monitorDisplaySettingDlg *ui;
MonitorPanel* _parent; MonitorPanel* _parent;

View File

@ -16,6 +16,8 @@ public:
void initial(); void initial();
void setSvgFile(const QByteArray &bytSvg); void setSvgFile(const QByteArray &bytSvg);
void setColors(const QColor &color); void setColors(const QColor &color);
void setCurType(const QString& str) {m_curDeviceType = str;}
void clearSvg();
QByteArray getCurSvg() {return _curSvg;} QByteArray getCurSvg() {return _curSvg;}
protected: protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
@ -23,6 +25,7 @@ private:
QSvgRenderer m_renderer; QSvgRenderer m_renderer;
QByteArray _curSvg; QByteArray _curSvg;
QColor m_Color; QColor m_Color;
QString m_curDeviceType; //当前设备类型对应设备tag
}; };
#endif #endif

View File

@ -2795,9 +2795,10 @@ void FixedPortsModel::updateMonitorDisplay()
auto pPro = pItem->getProperty(); auto pPro = pItem->getProperty();
if(pPro){ if(pPro){
QString sMeta = pPro->metaModelName(); QString sMeta = pPro->metaModelName();
for(auto iter = m_monitorDisplaySetting.begin();iter != m_monitorDisplaySetting.end();++iter){ for(auto iter = m_monitorDisplaySetting.begin();iter != m_monitorDisplaySetting.end();++iter){ //将设置的显示数据更新到item(显示数据不放入item的property)
if(iter.key().sTag == sMeta){ if(iter.key().sTag == sMeta){
pItem->setMonitorDisplayInfo(iter.value()); pItem->setMonitorDisplayInfo(iter.value());
pItem->updateCurState(monitorItemState::Normal);
break; break;
} }
} }

View File

@ -99,7 +99,11 @@ void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphic
} }
else else
{ {
painter->setPen(m_pen); if(_curMonitorStateEnable){ //当前状态被设置
painter->setPen(QPen(_curMonitorStateColor));
}
else
painter->setPen(m_pen);
} }
painter->setBrush(m_brush); painter->setBrush(m_brush);

View File

@ -83,6 +83,18 @@ void ElectricSvgGroup::paint(QPainter* painter, const QStyleOptionGraphicsItem*
} }
} }
void ElectricSvgGroup::updateCurState(monitorItemState e)
{
GraphicsProjectModelItem::updateCurState(e);
for(auto& p:m_childItems){
auto pItem = dynamic_cast<ElectricSvgItem*>(p);
if(pItem){
pItem->updateCurState(e);
}
}
}
void ElectricSvgGroup::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint) void ElectricSvgGroup::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{ {
switch (nHandle) switch (nHandle)
@ -122,6 +134,17 @@ void ElectricSvgGroup::updateMapSvg(QMap<QString,QByteArray> map)
m_mapSvg = map; m_mapSvg = map;
} }
void ElectricSvgGroup::setMonitorDisplayInfo(QMap<monitorItemStateStruct,monitorItemDisplayInfo> info)
{
GraphicsProjectModelItem::setMonitorDisplayInfo(info);
for(auto& p:m_childItems){
auto pItem = dynamic_cast<ElectricSvgItem*>(p);
if(pItem){
pItem->setMonitorDisplayInfo(info);
}
}
}
void ElectricSvgGroup::addSvgItem(ElectricSvgItem* item) void ElectricSvgGroup::addSvgItem(ElectricSvgItem* item)
{ {
item->setParentItem(this); // 关键:设置父项 item->setParentItem(this); // 关键:设置父项

View File

@ -7,7 +7,7 @@
#include <QDebug> #include <QDebug>
ElectricSvgItem::ElectricSvgItem(const QRect &rect, bool autoGenPort,QGraphicsItem *parent) ElectricSvgItem::ElectricSvgItem(const QRect &rect, bool autoGenPort,QGraphicsItem *parent)
: GraphicsProjectModelItem(parent),m_pRender(nullptr) : GraphicsProjectModelItem(parent),m_pRender(nullptr),m_pCustomRender(nullptr)
{ {
m_lastBoudingRect = rect; m_lastBoudingRect = rect;
m_boundingRect = rect; m_boundingRect = rect;
@ -21,7 +21,7 @@ ElectricSvgItem::ElectricSvgItem(const QRect &rect, bool autoGenPort,QGraphicsIt
} }
ElectricSvgItem::ElectricSvgItem(const ElectricSvgItem& obj) ElectricSvgItem::ElectricSvgItem(const ElectricSvgItem& obj)
: GraphicsProjectModelItem(obj) : GraphicsProjectModelItem(obj),m_pCustomRender(nullptr)
{ {
m_lastBoudingRect = obj.m_lastBoudingRect; m_lastBoudingRect = obj.m_lastBoudingRect;
m_boundingRect = obj.m_boundingRect; m_boundingRect = obj.m_boundingRect;
@ -79,9 +79,44 @@ void ElectricSvgItem::updateCoordinate() //当执行了resie和editShape函数
void ElectricSvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void ElectricSvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{ {
if(m_pRender) if(_curMonitorStateEnable){
{
m_pRender->render(painter,m_boundingRect); painter->setRenderHint(QPainter::Antialiasing);
QSize imageSize = m_boundingRect.size().toSize();
if (imageSize.isEmpty()) return;
// 1. 渲染SVG到图像
QImage sourceImage(imageSize, QImage::Format_ARGB32_Premultiplied);
sourceImage.fill(Qt::transparent);
QPainter sourcePainter(&sourceImage);
sourcePainter.setRenderHint(QPainter::Antialiasing);
m_pCustomRender->render(&sourcePainter, QRectF(0, 0, imageSize.width(), imageSize.height()));
sourcePainter.end();
// 2. 直接使用合成模式改变颜色(更高效)
QImage resultImage(imageSize, QImage::Format_ARGB32_Premultiplied);
resultImage.fill(Qt::transparent);
QPainter resultPainter(&resultImage);
// 先绘制原始SVG保留透明度
resultPainter.drawImage(0, 0, sourceImage);
// 然后对非透明区域应用颜色叠加
resultPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
resultPainter.fillRect(resultImage.rect(), QColor(_curMonitorStateColor));
resultPainter.end();
// 3. 最终绘制
painter->drawImage(m_boundingRect, resultImage);
}
else{
if(m_pRender)
{
m_pRender->render(painter,m_boundingRect);
}
} }
painter->setPen(m_pen); painter->setPen(m_pen);
@ -159,3 +194,14 @@ void ElectricSvgItem::editShape(int nHandle,const QPointF& ptMouse)
prepareGeometryChange(); prepareGeometryChange();
updateHandles(); updateHandles();
} }
void ElectricSvgItem::updateCurState(monitorItemState e)
{
GraphicsProjectModelItem::updateCurState(e);
if(m_pCustomRender == nullptr){
m_pCustomRender = new QSvgRenderer(_curMonitorStateSvg);
}
else{
m_pCustomRender->load(_curMonitorStateSvg);
}
}

View File

@ -45,28 +45,81 @@ void ElectricSvgItemCT::initial()
void ElectricSvgItemCT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void ElectricSvgItemCT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{ {
if (!m_pRender || !m_pRender->isValid())
return;
// 计算每个图形的宽度 // 计算每个图形的宽度
qreal singleWidth = m_boundingRect.width() / 3.0; qreal singleWidth = m_boundingRect.width() / 3.0;
// 绘制第一个图形 if(_curMonitorStateEnable){
if(_itemType == 1){
QRectF rect1(m_boundingRect.x(), m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect1);
// 绘制第二个图形 painter->setRenderHint(QPainter::Antialiasing);
QRectF rect2(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect2);
// 绘制第三个图形 QSize imageSize = m_boundingRect.size().toSize();
QRectF rect3(m_boundingRect.x() + 2 * singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height()); if (imageSize.isEmpty()) return;
m_pRender->render(painter, rect3);
// 1. 渲染SVG到图像
QImage sourceImage(imageSize, QImage::Format_ARGB32_Premultiplied);
sourceImage.fill(Qt::transparent);
QPainter sourcePainter(&sourceImage);
sourcePainter.setRenderHint(QPainter::Antialiasing);
m_pCustomRender->render(&sourcePainter, QRectF(0, 0, imageSize.width(), imageSize.height()));
sourcePainter.end();
// 2. 直接使用合成模式改变颜色(更高效)
QImage resultImage(imageSize, QImage::Format_ARGB32_Premultiplied);
resultImage.fill(Qt::transparent);
QPainter resultPainter(&resultImage);
// 先绘制原始SVG保留透明度
resultPainter.drawImage(0, 0, sourceImage);
// 然后对非透明区域应用颜色叠加
resultPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
resultPainter.fillRect(resultImage.rect(), QColor(_curMonitorStateColor));
resultPainter.end();
// 3. 最终绘制
//QRectF rect(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
//painter->drawImage(rect, resultImage);
if(_itemType == 1){
QRectF rect1(m_boundingRect.x(), m_boundingRect.y(), singleWidth, m_boundingRect.height());
painter->drawImage(rect1, resultImage);
// 绘制第二个图形
QRectF rect2(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
painter->drawImage(rect2, resultImage);
// 绘制第三个图形
QRectF rect3(m_boundingRect.x() + 2 * singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
painter->drawImage(rect3, resultImage);
}
else if(_itemType == 0){
QRectF rect(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
painter->drawImage(rect, resultImage);
}
} }
else if(_itemType == 0){ else{
QRectF rect(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height()); if (!m_pRender || !m_pRender->isValid())
m_pRender->render(painter, rect); return;
// 绘制第一个图形
if(_itemType == 1){
QRectF rect1(m_boundingRect.x(), m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect1);
// 绘制第二个图形
QRectF rect2(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect2);
// 绘制第三个图形
QRectF rect3(m_boundingRect.x() + 2 * singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect3);
}
else if(_itemType == 0){
QRectF rect(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height());
m_pRender->render(painter, rect);
}
} }
} }

View File

@ -32,9 +32,44 @@ ElectricSvgItemPT* ElectricSvgItemPT::clone() const
void ElectricSvgItemPT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void ElectricSvgItemPT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{ {
if (!m_pRender || !m_pRender->isValid()) if(_curMonitorStateEnable){
return;
m_pRender->render(painter, m_boundingRect); painter->setRenderHint(QPainter::Antialiasing);
QSize imageSize = m_boundingRect.size().toSize();
if (imageSize.isEmpty()) return;
// 1. 渲染SVG到图像
QImage sourceImage(imageSize, QImage::Format_ARGB32_Premultiplied);
sourceImage.fill(Qt::transparent);
QPainter sourcePainter(&sourceImage);
sourcePainter.setRenderHint(QPainter::Antialiasing);
m_pCustomRender->render(&sourcePainter, QRectF(0, 0, imageSize.width(), imageSize.height()));
sourcePainter.end();
// 2. 直接使用合成模式改变颜色(更高效)
QImage resultImage(imageSize, QImage::Format_ARGB32_Premultiplied);
resultImage.fill(Qt::transparent);
QPainter resultPainter(&resultImage);
// 先绘制原始SVG保留透明度
resultPainter.drawImage(0, 0, sourceImage);
// 然后对非透明区域应用颜色叠加
resultPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
resultPainter.fillRect(resultImage.rect(), QColor(_curMonitorStateColor));
resultPainter.end();
// 3. 最终绘制
painter->drawImage(m_boundingRect, resultImage);
}
else{
if (!m_pRender || !m_pRender->isValid())
return;
m_pRender->render(painter, m_boundingRect);
}
} }
void ElectricSvgItemPT::initial() void ElectricSvgItemPT::initial()

View File

@ -52,7 +52,7 @@ GraphicsBaseItem::GraphicsBaseItem(const GraphicsBaseItem& obj)
} }
for(auto& port:obj.m_mapPort){ for(auto& port:obj.m_mapPort){
addPort(tpe,port->pos(),port->getId(),port->getType(),port->portPos()); addPort(tpe,port->pos(),port->getId(),port->getType(),port->portPos(),port->getXPercent(),port->getYPercent());
} }
} }
@ -465,6 +465,7 @@ GraphicsProjectModelItem::GraphicsProjectModelItem(QGraphicsItem *parent)
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
_curMonitorState = monitorItemState::Normal; _curMonitorState = monitorItemState::Normal;
_curMonitorStateEnable = false;
} }
GraphicsProjectModelItem::GraphicsProjectModelItem(const GraphicsProjectModelItem& obj) GraphicsProjectModelItem::GraphicsProjectModelItem(const GraphicsProjectModelItem& obj)
@ -507,6 +508,7 @@ GraphicsProjectModelItem::GraphicsProjectModelItem(const GraphicsProjectModelIte
setRotation(obj.rotation()); setRotation(obj.rotation());
_curMonitorState = monitorItemState::Normal; _curMonitorState = monitorItemState::Normal;
_curMonitorStateEnable = false;
} }
GraphicsProjectModelItem::~GraphicsProjectModelItem() GraphicsProjectModelItem::~GraphicsProjectModelItem()

View File

@ -4,6 +4,7 @@
#include <QColorDialog> #include <QColorDialog>
#include <QSvgRenderer> #include <QSvgRenderer>
#include <QPainter> #include <QPainter>
#include <QMessageBox>
#include "projectModelManager.h" #include "projectModelManager.h"
#include "projectIconSelectionDlg.h" #include "projectIconSelectionDlg.h"
@ -27,8 +28,8 @@ void MonitorDisplaySettingDlg::initial()
connect(ui->btn_save,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onSaveClicked); connect(ui->btn_save,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onSaveClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onCancelClicked); connect(ui->btn_cancel,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onCancelClicked);
connect(ui->cb_type,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onTypeChanged); connect(ui->cb_type,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onDeviceComboBoxChanged);
connect(ui->cb_state,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onStateChanged); connect(ui->cb_state,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onStateComboBoxChanged);
connect(ui->btn_selectColor, &QPushButton::clicked, this, [this]() { connect(ui->btn_selectColor, &QPushButton::clicked, this, [this]() {
QColor newColor = QColorDialog::getColor(_curColor, this, "选择颜色"); QColor newColor = QColorDialog::getColor(_curColor, this, "选择颜色");
@ -41,7 +42,7 @@ void MonitorDisplaySettingDlg::initial()
ui->btn_selectColor->setText(newColor.name()); ui->btn_selectColor->setText(newColor.name());
// 触发预览更新 // 触发预览更新
if(_curType.notEmpty() && _curState.notEmpty()){ if(_curType.isValid() && _curState.isValid()){
_tempSetting[_curType][_curState].sColor = _curColor.name(); _tempSetting[_curType][_curState].sColor = _curColor.name();
ui->content->setColors(_curColor); ui->content->setColors(_curColor);
} }
@ -56,18 +57,33 @@ void MonitorDisplaySettingDlg::showDlg()
{ {
show(); show();
_tempSetting = _parent->getModelController()->getMonitorDisplaySetting(); _tempSetting = _parent->getModelController()->getMonitorDisplaySetting();
ui->cb_state->blockSignals(true);
ui->cb_type->blockSignals(true);
ui->cb_type->clear(); ui->cb_type->clear();
ui->cb_state->clear(); ui->cb_state->clear();
ui->cb_state->blockSignals(false);
ui->cb_type->blockSignals(false);
for(auto iter = _tempSetting.begin();iter != _tempSetting.end();++iter){ for(auto iter = _tempSetting.begin();iter != _tempSetting.end();++iter){
ui->cb_type->addItem(iter.key().sName,iter.key().sTag); ui->cb_type->addItem(iter.key().sName,iter.key().sTag);
} }
// 2. 如果有设备,选择第一个设备
// if (ui->cb_type->count() > 0) {
// QString firstDevice = ui->cb_type->itemText(0);
// onDeviceComboBoxChanged(firstDevice);
// }
} }
void MonitorDisplaySettingDlg::onSaveClicked() void MonitorDisplaySettingDlg::onSaveClicked()
{ {
saveSetting(_curType,_curState); if (validateCurrentDeviceState()) {
if (!saveCurrentSettingsWithIcon()) {
QMessageBox::warning(this, "Warning", "Failed to save current settings");
}
}
_parent->getModelController()->getMonitorDisplaySetting() = _tempSetting; _parent->getModelController()->getMonitorDisplaySetting() = _tempSetting;
_parent->getModelController()->updateMonitorDisplay();
hide(); hide();
} }
@ -96,22 +112,50 @@ void MonitorDisplaySettingDlg::onCheckboxToggled(bool val)
void MonitorDisplaySettingDlg::onIconSelectClicked() void MonitorDisplaySettingDlg::onIconSelectClicked()
{ {
if(!_curMeta.isEmpty() && !_curModel.isEmpty()){ // if(!_curMeta.isEmpty() && !_curModel.isEmpty()){
auto mapAllSvg = ProjectModelManager::instance().getData()[_curMeta][_curModel].modelSetting.mapSvg; // auto mapAllSvg = ProjectModelManager::instance().getData()[_curMeta][_curModel].modelSetting.mapSvg;
ProjectIconSelectionDlg dialog(mapAllSvg, this); // ProjectIconSelectionDlg dialog(mapAllSvg, this);
if (dialog.exec() == QDialog::Accepted) { // if (dialog.exec() == QDialog::Accepted) {
QByteArray selectedSVG = dialog.selectedSVG(); // QByteArray selectedSVG = dialog.selectedSVG();
if (!selectedSVG.isEmpty()) { // if (!selectedSVG.isEmpty()) {
QSvgRenderer renderer(selectedSVG); // QSvgRenderer renderer(selectedSVG);
QPixmap pixmap(32, 32); // QPixmap pixmap(32, 32);
pixmap.fill(Qt::transparent); // pixmap.fill(Qt::transparent);
QPainter painter(&pixmap); // QPainter painter(&pixmap);
renderer.render(&painter); // renderer.render(&painter);
ui->btn_selectIcon->setIcon(QIcon(pixmap)); // ui->btn_selectIcon->setIcon(QIcon(pixmap));
ui->content->setSvgFile(selectedSVG); // if (validateSvgData(selectedSVG)) {
// updateIconDisplay(selectedSVG);
if(_curType.notEmpty() && _curState.notEmpty()){ // if(_curType.isValid() && _curState.isValid()){
// _tempSetting[_curType][_curState].bytPicture = selectedSVG;
// }
// }
// }
// }
// }
if(_curMeta.isEmpty() || _curModel.isEmpty()){
return;
}
auto mapAllSvg = ProjectModelManager::instance().getData()[_curMeta][_curModel].modelSetting.mapSvg;
ProjectIconSelectionDlg dialog(mapAllSvg, this);
if (dialog.exec() == QDialog::Accepted) {
QByteArray selectedSVG = dialog.selectedSVG();
if (!selectedSVG.isEmpty()) {
QSvgRenderer renderer(selectedSVG);
QPixmap pixmap(32, 32);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
renderer.render(&painter);
ui->btn_selectIcon->setIcon(QIcon(pixmap));
if (validateSvgData(selectedSVG)) {
updateIconDisplay(selectedSVG);
// 立即更新当前设备状态的图标数据
if(_curType.isValid() && _curState.isValid()){
_tempSetting[_curType][_curState].bytPicture = selectedSVG; _tempSetting[_curType][_curState].bytPicture = selectedSVG;
} }
} }
@ -119,80 +163,59 @@ void MonitorDisplaySettingDlg::onIconSelectClicked()
} }
} }
void MonitorDisplaySettingDlg::onTypeChanged(const QString& str) void MonitorDisplaySettingDlg::onDeviceComboBoxChanged(const QString& str)
{ {
/*saveSetting(_curType,_curState); if (str.isEmpty()) {
ui->cb_state->clear(); return;
monitorItemTypeStruct keyType;
keyType.sTag = ui->cb_type->currentData().toString();
keyType.sName = str;
QMap<monitorItemStateStruct,monitorItemDisplayInfo> mapInfo = _tempSetting.value(keyType);
for(auto iter = mapInfo.begin();iter != mapInfo.end();++iter){
ui->cb_state->addItem(iter.key().sState,int(iter.key().eState));
if(_curMeta != iter->sMeta){
_curMeta = iter->sMeta;
}
} }
_curType = keyType;
onStateChanged(ui->cb_state->currentText());*/
//monitorItemStateStruct keyState; // 1. 保存当前设备的非图标数据
//keyState.sState = ui->cb_state->currentText(); if (_curType.isValid() && _curState.isValid()) {
//loadSetting(_curType,ui->cb_state->currentText()); saveCurrentSettingsWithIcon();
// 1. 保存当前设备类型的设置 clearIconDisplay();
saveSetting(_curType, _curState); }
// 2. 清空状态下拉框 // 2. 构建新设备
ui->cb_state->clear(); monitorItemTypeStruct newType;
newType.sTag = ui->cb_type->currentData().toString();
newType.sName = str;
// 3. 构建新的设备类型键值 if (!newType.isValid()) {
monitorItemTypeStruct keyType; return;
keyType.sTag = ui->cb_type->currentData().toString(); }
keyType.sName = str;
// 4. 获取新设备类型对应的状态列表 // 3. 检查新设备是否存在
QMap<monitorItemStateStruct, monitorItemDisplayInfo> mapInfo = _tempSetting.value(keyType); if (!_tempSetting.contains(newType)) {
_curType = newType;
// 5. 如果新设备类型没有状态数据,直接返回 _curState = monitorItemStateStruct();
if (mapInfo.isEmpty()) {
_curType = keyType;
// 清空当前状态相关显示
clearStateDisplay(); clearStateDisplay();
return; return;
} }
// 6. 填充状态下拉框 // 4. 清空状态下拉框
QString firstState; // 记录第一个状态,用于后续加载 ui->cb_state->blockSignals(true);
for (auto iter = mapInfo.begin(); iter != mapInfo.end(); ++iter) { ui->cb_state->clear();
QString stateName = iter.key().sState; ui->cb_state->blockSignals(false);
int stateValue = static_cast<int>(iter.key().eState);
ui->cb_state->addItem(stateName, stateValue); // 5. 填充新设备的状态
auto& stateMap = _tempSetting[newType];
// 记录第一个状态 for (auto iter = stateMap.begin(); iter != stateMap.end(); ++iter) {
if (firstState.isEmpty()) { ui->cb_state->addItem(iter.key().sState, static_cast<int>(iter.key().eState));
firstState = stateName;
}
// 更新元数据(如果有变化)
if (_curMeta != iter->sMeta) {
_curMeta = iter->sMeta;
}
} }
// 7. 更新当前设备类型 // 6. 更新当前设备
_curType = keyType; _curType = newType;
// 8. 加载第一个状态的设置 // 7. 加载第一个状态
if (!firstState.isEmpty()) { if (ui->cb_state->count() > 0) {
// 设置下拉框当前项为第一个状态 loadFirstStateSafely();
ui->cb_state->setCurrentIndex(0); } else {
// 触发状态变化处理 _curState = monitorItemStateStruct();
onStateChanged(firstState); clearStateDisplay();
} }
} }
void MonitorDisplaySettingDlg::onStateChanged(const QString& str) void MonitorDisplaySettingDlg::onStateComboBoxChanged(const QString& str)
{ {
/*if(_tempSetting.contains(_curType)){ /*if(_tempSetting.contains(_curType)){
monitorItemStateStruct keyState; monitorItemStateStruct keyState;
@ -209,120 +232,228 @@ void MonitorDisplaySettingDlg::onStateChanged(const QString& str)
loadSetting(_curType,_curState); loadSetting(_curType,_curState);
} }
}*/ }*/
// 1. 检查当前设备类型是否存在
if (!_tempSetting.contains(_curType)) { if (str.isEmpty() || str == _curState.sState) {
return; return;
} }
// 2. 检查状态是否为空 // 1. 保存当前状态的完整数据(包括图标)
if (str.isEmpty()) { if (_curType.isValid() && _curState.isValid()) {
return; saveCurrentSettingsWithIcon(); // 保存完整数据
} }
// 3. 构建状态键值 // 2. 获取新状态
monitorItemStateStruct keyState;
keyState.sState = str;
// 4. 从下拉框获取状态枚举值(添加安全检查)
QVariant stateData = ui->cb_state->currentData(); QVariant stateData = ui->cb_state->currentData();
if (!stateData.isValid()) { if (!stateData.isValid()) {
return; return;
} }
bool ok = false; monitorItemStateStruct newState;
int stateValue = stateData.toInt(&ok); newState.sState = str;
if (!ok) { newState.eState = static_cast<monitorItemState>(stateData.toInt());
return;
}
keyState.eState = monitorItemState(stateValue); // 3. 更新当前状态
_curState = newState;
// 5. 检查状态是否存在 // 4. 加载新状态设置
auto& typeSettings = _tempSetting[_curType];
if (!typeSettings.contains(keyState)) {
return;
}
// 6. 保存当前设置
saveSetting(_curType, _curState);
// 7. 获取新状态信息
auto& info = typeSettings[keyState];
// 8. 更新界面控件
ui->checkBox_custom->setChecked(info.bEnable);
// 9. 更新模型信息(仅在变化时)
if (_curModel != info.sModel) {
_curModel = info.sModel;
}
// 10. 更新当前状态并加载新设置
_curState = keyState;
loadSetting(_curType, _curState); loadSetting(_curType, _curState);
} }
void MonitorDisplaySettingDlg::loadSetting(monitorItemTypeStruct type,monitorItemStateStruct state) void MonitorDisplaySettingDlg::loadSetting(monitorItemTypeStruct type, monitorItemStateStruct state)
{ {
auto setting = _tempSetting[type][state]; if (!type.isValid() || !state.isValid()) {
return;
}
if (!_tempSetting.contains(type) || !_tempSetting[type].contains(state)) {
return;
}
auto& setting = _tempSetting[type][state];
// 修复正确设置_curMeta和_curModel
_curMeta = setting.sMeta;
_curModel = setting.sModel;
// 更新界面控件
ui->checkBox_custom->setChecked(setting.bEnable); ui->checkBox_custom->setChecked(setting.bEnable);
if(setting.bEnable){
ui->btn_selectColor->setEnabled(true); // 设置控件可用性
ui->btn_selectIcon->setEnabled(true); bool enabled = setting.bEnable;
ui->sb_width->setEnabled(true); ui->btn_selectColor->setEnabled(enabled);
ui->sb_height->setEnabled(true); ui->btn_selectIcon->setEnabled(enabled);
ui->cb_effect->setEnabled(true); ui->sb_width->setEnabled(enabled);
} ui->sb_height->setEnabled(enabled);
else{ ui->cb_effect->setEnabled(enabled);
ui->btn_selectColor->setEnabled(false);
ui->btn_selectIcon->setEnabled(false); // 更新颜色
ui->sb_width->setEnabled(false);
ui->sb_height->setEnabled(false);
ui->cb_effect->setEnabled(false);
}
_curColor = QColor(setting.sColor); _curColor = QColor(setting.sColor);
// 更新按钮显示 if (!_curColor.isValid()) {
QPixmap pixmap(16, 16); _curColor = Qt::black;
pixmap.fill(_curColor); }
ui->btn_selectColor->setIcon(QIcon(pixmap));
QPixmap colorPixmap(16, 16);
colorPixmap.fill(_curColor);
ui->btn_selectColor->setIcon(QIcon(colorPixmap));
ui->btn_selectColor->setText(_curColor.name()); ui->btn_selectColor->setText(_curColor.name());
QSvgRenderer renderer(setting.bytPicture); // 更新图标
QPixmap pixSvg(32, 32); if (!setting.bytPicture.isEmpty()) {
pixmap.fill(Qt::transparent); QSvgRenderer renderer(setting.bytPicture);
QPainter painter(&pixSvg); if (renderer.isValid()) {
renderer.render(&painter); QPixmap iconPixmap(32, 32);
iconPixmap.fill(Qt::transparent);
QPainter painter(&iconPixmap);
renderer.render(&painter);
ui->btn_selectIcon->setIcon(QIcon(iconPixmap));
ui->btn_selectIcon->setIcon(QIcon(pixSvg)); ui->content->setSvgFile(setting.bytPicture);
ui->content->setSvgFile(setting.bytPicture); }
ui->content->setColors(_curColor); } else {
ui->btn_selectIcon->setIcon(QIcon());
ui->content->clearSvg();
}
// 更新尺寸
ui->sb_width->setValue(setting.nWidth); ui->sb_width->setValue(setting.nWidth);
ui->sb_height->setValue(setting.nHeight); ui->sb_height->setValue(setting.nHeight);
// 更新内容显示
ui->content->setCurType(type.sTag);
ui->content->setColors(_curColor);
} }
void MonitorDisplaySettingDlg::saveSetting(monitorItemTypeStruct type,monitorItemStateStruct state)
bool MonitorDisplaySettingDlg::saveCurrentSettingsWithIcon()
{ {
if(type.notEmpty() && state.notEmpty()){ if (!_curType.isValid() || !_curState.isValid()) {
auto& setting = _tempSetting[type][state]; return false;
setting.bEnable = ui->checkBox_custom->isChecked();
setting.sColor = _curColor.name();
setting.bytPicture = ui->content->getCurSvg();
setting.nWidth = ui->sb_width->value();
setting.nHeight = ui->sb_height->value();
} }
}
void MonitorDisplaySettingDlg::updatePreview() if (!_tempSetting.contains(_curType) || !_tempSetting[_curType].contains(_curState)) {
{ return false;
ui->content->update(); }
auto& setting = _tempSetting[_curType][_curState];
int oldSvgSize = setting.bytPicture.size();
// 保存所有数据,包括图标
setting.bEnable = ui->checkBox_custom->isChecked();
setting.sColor = _curColor.name(QColor::HexArgb);
// 图标数据:使用当前显示的图标
QByteArray currentSvg = ui->content->getCurSvg();
if (!currentSvg.isEmpty() && validateSvgData(currentSvg)) {
setting.bytPicture = currentSvg;
}
// 如果图标数据无效,保持原数据不变
setting.nWidth = ui->sb_width->value();
setting.nHeight = ui->sb_height->value();
// 修复_curMeta和_curModel
if (!_curMeta.isEmpty()) {
setting.sMeta = _curMeta;
}
if (!_curModel.isEmpty()) {
setting.sModel = _curModel;
}
return true;
} }
void MonitorDisplaySettingDlg::clearStateDisplay() void MonitorDisplaySettingDlg::clearStateDisplay()
{ {
ui->checkBox_custom->setChecked(false); ui->checkBox_custom->setChecked(false);
// 可以添加其他需要清空的UI元素 ui->btn_selectColor->setEnabled(false);
_curState = monitorItemStateStruct(); // 清空当前状态 ui->btn_selectIcon->setEnabled(false);
_curModel = QString(); // 清空当前模型 ui->sb_width->setEnabled(false);
_curMeta = QString(); // 清空元数据 ui->sb_height->setEnabled(false);
ui->cb_effect->setEnabled(false);
// 清空图标显示
ui->btn_selectIcon->setIcon(QIcon());
ui->content->clearSvg();
// 重置颜色显示
_curColor = Qt::black;
QPixmap pixmap(16, 16);
pixmap.fill(_curColor);
ui->btn_selectColor->setIcon(QIcon(pixmap));
ui->btn_selectColor->setText(_curColor.name());
// 清空当前状态
_curState = monitorItemStateStruct();
_curModel.clear();
_curMeta.clear();
} }
void MonitorDisplaySettingDlg::updateIconDisplay(const QByteArray& svgData)
{
if (svgData.isEmpty()) {
clearIconDisplay();
return;
}
if (!validateSvgData(svgData)) {
clearIconDisplay();
return;
}
try {
// 更新按钮图标
QSvgRenderer renderer(svgData);
QPixmap iconPixmap(32, 32);
iconPixmap.fill(Qt::transparent);
QPainter painter(&iconPixmap);
renderer.render(&painter);
ui->btn_selectIcon->setIcon(QIcon(iconPixmap));
// 更新内容显示
ui->content->setSvgFile(svgData);
ui->content->setColors(_curColor);
} catch (...) {
clearIconDisplay();
}
}
void MonitorDisplaySettingDlg::clearIconDisplay()
{
ui->btn_selectIcon->setIcon(QIcon());
ui->content->clearSvg();
}
bool MonitorDisplaySettingDlg::validateSvgData(const QByteArray& svgData) const
{
if (svgData.isEmpty()) {
return false;
}
QSvgRenderer renderer(svgData);
return renderer.isValid();
}
void MonitorDisplaySettingDlg::loadFirstStateSafely()
{
QString firstStateName = ui->cb_state->itemText(0);
QVariant firstStateData = ui->cb_state->itemData(0);
monitorItemStateStruct firstState;
firstState.sState = firstStateName;
firstState.eState = static_cast<monitorItemState>(firstStateData.toInt());
_curState = firstState;
ui->cb_state->setCurrentIndex(0);
loadSetting(_curType, _curState);
}
bool MonitorDisplaySettingDlg::validateCurrentDeviceState() const
{
return _curType.isValid() && _curState.isValid() &&
_tempSetting.contains(_curType) &&
_tempSetting[_curType].contains(_curState);
}

View File

@ -30,29 +30,54 @@ void MonitorItemPreviewDlg::setColors(const QColor &color)
update(); update();
} }
void MonitorItemPreviewDlg::clearSvg()
{
QByteArray emptySvg = "<svg xmlns='http://www.w3.org/2000/svg'/>";
_curSvg.clear();
m_renderer.load(emptySvg);
m_curDeviceType.clear();
}
void MonitorItemPreviewDlg::paintEvent(QPaintEvent *) { void MonitorItemPreviewDlg::paintEvent(QPaintEvent *) {
QPainter painter(this); if(m_curDeviceType == "cable"){
painter.setRenderHint(QPainter::Antialiasing); QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 1. 先将SVG渲染到一个透明图像上作为遮罩 // 设置线宽
QImage maskImage(size(), QImage::Format_ARGB32); int lineWidth = 3;
maskImage.fill(Qt::transparent); painter.setPen(QPen(m_Color, lineWidth));
QPainter maskPainter(&maskImage); // 定义折线的各个顶点
m_renderer.render(&maskPainter); QPolygon polyline;
maskPainter.end(); polyline << QPoint(20, 20) // 起点:左上角
<< QPoint(width()/2, height()/2) // 中间点:中心
<< QPoint(width()-20, height()-20); // 终点:右下角
painter.drawPolyline(polyline);
}
else{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 2. 使用目标颜色填充但只在SVG的非透明区域显示 // 1. 先将SVG渲染到一个透明图像上作为遮罩
painter.setCompositionMode(QPainter::CompositionMode_SourceOver); QImage maskImage(size(), QImage::Format_ARGB32);
maskImage.fill(Qt::transparent);
for (int y = 0; y < maskImage.height(); ++y) { QPainter maskPainter(&maskImage);
for (int x = 0; x < maskImage.width(); ++x) { m_renderer.render(&maskPainter);
QRgb pixel = maskImage.pixel(x, y); maskPainter.end();
if (qAlpha(pixel) > 0) { // 只处理非透明像素
// 保持原始透明度,只改变颜色 // 2. 使用目标颜色填充但只在SVG的非透明区域显示
QColor newColor = m_Color; painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
newColor.setAlpha(qAlpha(pixel)); // 保持原始alpha值
painter.fillRect(x, y, 1, 1, newColor); for (int y = 0; y < maskImage.height(); ++y) {
for (int x = 0; x < maskImage.width(); ++x) {
QRgb pixel = maskImage.pixel(x, y);
if (qAlpha(pixel) > 0) { // 只处理非透明像素
// 保持原始透明度,只改变颜色
QColor newColor = m_Color;
newColor.setAlpha(qAlpha(pixel)); // 保持原始alpha值
painter.fillRect(x, y, 1, 1, newColor);
}
} }
} }
} }