diff --git a/common/include/global.h b/common/include/global.h index 70cd7c1..f71f351 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -1108,7 +1108,8 @@ struct monitorItemAttributeInfo //单个监控item属性 }; enum class monitorItemState{ //监控item的状态 - Closing = 0, //合闸 + Normal = 0, //正常 + Closing, //合闸 Opening, //分闸 AccidentTrip, //事故跳闸 StatusFault, //状态故障 @@ -1118,7 +1119,6 @@ enum class monitorItemState{ //监控item的状态 Running, //运行 ShutDown, //停运 Alarm, //告警 - Normal, //正常 LineBreak, //断线 MeasureMentOutLimit //量测越限 }; @@ -1138,39 +1138,37 @@ struct monitorItemDisplayInfo //监控模式显示信息 struct monitorItemTypeStruct //监控设备类型 { - QString sTag; //英文 + QString sTag; QString sName; - bool operator<(const monitorItemTypeStruct& other) const { - if (sTag != other.sTag) - return sTag < other.sTag; - return sName < other.sName; + bool isValid() const { + return !sTag.isEmpty() && !sName.isEmpty(); } - bool notEmpty(){ - if(!sTag.isEmpty() && !sName.isEmpty()) - return true; - else - return false; + bool operator==(const monitorItemTypeStruct& other) const { + return sTag == other.sTag && sName == other.sName; + } + + bool operator<(const monitorItemTypeStruct& other) const { + return sTag < other.sTag || (sTag == other.sTag && sName < other.sName); } }; struct monitorItemStateStruct //监控设备状态 { - monitorItemState eState; - QString sState; //状态(中文) + QString sState; + monitorItemState eState; - bool operator<(const monitorItemStateStruct& other) const { - if (eState != other.eState) - return eState < other.eState; - return sState < other.sState; + bool isValid() const { + return !sState.isEmpty(); } - bool notEmpty(){ - if(!sState.isEmpty()) - return true; - else - return false; + bool operator==(const monitorItemStateStruct& other) const { + return sState == other.sState && eState == other.eState; + } + + bool operator<(const monitorItemStateStruct& other) const { + return sState < other.sState || (sState == other.sState && eState < other.eState); } }; diff --git a/diagramCavas/include/graphicsItem/electricSvgGroup.h b/diagramCavas/include/graphicsItem/electricSvgGroup.h index 06d2f61..5dd1c0e 100644 --- a/diagramCavas/include/graphicsItem/electricSvgGroup.h +++ b/diagramCavas/include/graphicsItem/electricSvgGroup.h @@ -19,11 +19,13 @@ public: void move(const QPointF&) override; virtual void addSvgItem(ElectricSvgItem* item); virtual void updateMapSvg(QMap map); //工程模property不含图片,额外存储 - + virtual void setMonitorDisplayInfo(QMap info) override; //将显示数据更新到子item中 protected: virtual QPainterPath shape() override; virtual void editShape(int, const QPointF&) override; virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; +protected: + virtual void updateCurState(monitorItemState e) override; protected: QRectF m_lastBoudingRect; //记录上一时刻的boundingRect QMap m_mapSvg; diff --git a/diagramCavas/include/graphicsItem/electricSvgItem.h b/diagramCavas/include/graphicsItem/electricSvgItem.h index 4ec6821..b1a7d81 100644 --- a/diagramCavas/include/graphicsItem/electricSvgItem.h +++ b/diagramCavas/include/graphicsItem/electricSvgItem.h @@ -18,13 +18,15 @@ public: virtual void loadSvg(){}; virtual void loadSvg(QByteArray); //第二种load直接加载图片 virtual void updateMapSvg(QMap map); + virtual void updateCurState(monitorItemState e) override; protected: virtual QPainterPath shape() override; virtual void editShape(int, const QPointF&) override; virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; protected: QRectF m_lastBoudingRect; //记录上一时刻的boundingRect - QSvgRenderer* m_pRender; + QSvgRenderer* m_pRender; //默认 + QSvgRenderer* m_pCustomRender; //定制 QMap m_mapSvg; QByteArray _tempSvg; //保存直接加载的svg数据 }; diff --git a/diagramCavas/include/graphicsItem/graphicsBaseItem.h b/diagramCavas/include/graphicsItem/graphicsBaseItem.h index 206e496..18bdc64 100644 --- a/diagramCavas/include/graphicsItem/graphicsBaseItem.h +++ b/diagramCavas/include/graphicsItem/graphicsBaseItem.h @@ -177,7 +177,7 @@ class GraphicsBaseItem :public QObject, public AbstractShapeType virtual GraphicsBaseItem* clone() const = 0; 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 setEntity(PowerEntity*); //设置当前图元的拓扑数据 virtual PowerEntity* entity(); @@ -578,6 +578,15 @@ public: virtual void updateTerPos(); //ct,pt等item大小变动后重新计算端点位置 virtual void setCurMonitorState(monitorItemState sta) {_curMonitorState = sta;} //设置当前运行时模式 virtual void setMonitorDisplayInfo(QMap 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: virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&) override; virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; @@ -586,6 +595,23 @@ signals: void ifExist(QUuid id,const QString&,int type,GraphicsProjectModelItem*); public slots: 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: ItemState m_state; QPointF m_beginConnectPoint; @@ -593,6 +619,9 @@ protected: int _lastPort; //最后触碰的port QString _modelName; //当前图元使用的模型名,用来在model中检索属性信息 monitorItemState _curMonitorState; //当前运行时模式 + QColor _curMonitorStateColor; + QByteArray _curMonitorStateSvg; + bool _curMonitorStateEnable; QMap _displaySetting; //显示设置 }; diff --git a/diagramCavas/include/monitorDisplaySettingDlg.h b/diagramCavas/include/monitorDisplaySettingDlg.h index f2ac3eb..eaf1599 100644 --- a/diagramCavas/include/monitorDisplaySettingDlg.h +++ b/diagramCavas/include/monitorDisplaySettingDlg.h @@ -26,15 +26,22 @@ public slots: void onIconSelectClicked(); void onCheckboxToggled(bool); - void onTypeChanged(const QString&); - void onStateChanged(const QString&); + void onDeviceComboBoxChanged(const QString&); + void onStateComboBoxChanged(const QString&); private: - void loadSetting(monitorItemTypeStruct type,monitorItemStateStruct state); //载入设定到界面 - void saveSetting(monitorItemTypeStruct type,monitorItemStateStruct state); + void loadSetting(monitorItemTypeStruct type, monitorItemStateStruct state); + bool saveCurrentSettingsWithIcon(); + void loadFirstStateSafely(); - void updatePreview(); //预览更新 + // 图片处理 void clearStateDisplay(); + void updateIconDisplay(const QByteArray& svgData); + void clearIconDisplay(); + bool validateSvgData(const QByteArray& svgData) const; + + // 辅助方法 + bool validateCurrentDeviceState() const; private: Ui::monitorDisplaySettingDlg *ui; MonitorPanel* _parent; diff --git a/diagramCavas/include/monitorItemPreviewDlg.h b/diagramCavas/include/monitorItemPreviewDlg.h index eaade3e..d7f3a4c 100644 --- a/diagramCavas/include/monitorItemPreviewDlg.h +++ b/diagramCavas/include/monitorItemPreviewDlg.h @@ -16,6 +16,8 @@ public: void initial(); void setSvgFile(const QByteArray &bytSvg); void setColors(const QColor &color); + void setCurType(const QString& str) {m_curDeviceType = str;} + void clearSvg(); QByteArray getCurSvg() {return _curSvg;} protected: void paintEvent(QPaintEvent *) override; @@ -23,6 +25,7 @@ private: QSvgRenderer m_renderer; QByteArray _curSvg; QColor m_Color; + QString m_curDeviceType; //当前设备类型,对应设备tag }; #endif diff --git a/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp b/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp index b703ba4..d1223b7 100644 --- a/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp +++ b/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp @@ -2795,9 +2795,10 @@ void FixedPortsModel::updateMonitorDisplay() auto pPro = pItem->getProperty(); if(pPro){ 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){ pItem->setMonitorDisplayInfo(iter.value()); + pItem->updateCurState(monitorItemState::Normal); break; } } diff --git a/diagramCavas/source/graphicsItem/electricConnectLineItem.cpp b/diagramCavas/source/graphicsItem/electricConnectLineItem.cpp index 0abf631..0f23c35 100644 --- a/diagramCavas/source/graphicsItem/electricConnectLineItem.cpp +++ b/diagramCavas/source/graphicsItem/electricConnectLineItem.cpp @@ -99,7 +99,11 @@ void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphic } else { - painter->setPen(m_pen); + if(_curMonitorStateEnable){ //当前状态被设置 + painter->setPen(QPen(_curMonitorStateColor)); + } + else + painter->setPen(m_pen); } painter->setBrush(m_brush); diff --git a/diagramCavas/source/graphicsItem/electricSvgGroup.cpp b/diagramCavas/source/graphicsItem/electricSvgGroup.cpp index c580812..95aa385 100644 --- a/diagramCavas/source/graphicsItem/electricSvgGroup.cpp +++ b/diagramCavas/source/graphicsItem/electricSvgGroup.cpp @@ -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(p); + if(pItem){ + pItem->updateCurState(e); + } + } +} + + void ElectricSvgGroup::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint) { switch (nHandle) @@ -122,6 +134,17 @@ void ElectricSvgGroup::updateMapSvg(QMap map) m_mapSvg = map; } +void ElectricSvgGroup::setMonitorDisplayInfo(QMap info) +{ + GraphicsProjectModelItem::setMonitorDisplayInfo(info); + for(auto& p:m_childItems){ + auto pItem = dynamic_cast(p); + if(pItem){ + pItem->setMonitorDisplayInfo(info); + } + } +} + void ElectricSvgGroup::addSvgItem(ElectricSvgItem* item) { item->setParentItem(this); // 关键:设置父项 diff --git a/diagramCavas/source/graphicsItem/electricSvgItem.cpp b/diagramCavas/source/graphicsItem/electricSvgItem.cpp index 0f5adb9..73d5a87 100644 --- a/diagramCavas/source/graphicsItem/electricSvgItem.cpp +++ b/diagramCavas/source/graphicsItem/electricSvgItem.cpp @@ -7,7 +7,7 @@ #include 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_boundingRect = rect; @@ -21,7 +21,7 @@ ElectricSvgItem::ElectricSvgItem(const QRect &rect, bool autoGenPort,QGraphicsIt } ElectricSvgItem::ElectricSvgItem(const ElectricSvgItem& obj) - : GraphicsProjectModelItem(obj) + : GraphicsProjectModelItem(obj),m_pCustomRender(nullptr) { m_lastBoudingRect = obj.m_lastBoudingRect; m_boundingRect = obj.m_boundingRect; @@ -79,9 +79,44 @@ void ElectricSvgItem::updateCoordinate() //当执行了resie和editShape函数 void ElectricSvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - if(m_pRender) - { - m_pRender->render(painter,m_boundingRect); + if(_curMonitorStateEnable){ + + 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); @@ -159,3 +194,14 @@ void ElectricSvgItem::editShape(int nHandle,const QPointF& ptMouse) prepareGeometryChange(); updateHandles(); } + +void ElectricSvgItem::updateCurState(monitorItemState e) +{ + GraphicsProjectModelItem::updateCurState(e); + if(m_pCustomRender == nullptr){ + m_pCustomRender = new QSvgRenderer(_curMonitorStateSvg); + } + else{ + m_pCustomRender->load(_curMonitorStateSvg); + } +} diff --git a/diagramCavas/source/graphicsItem/electricSvgItemCT.cpp b/diagramCavas/source/graphicsItem/electricSvgItemCT.cpp index f4e84d6..72a5c27 100644 --- a/diagramCavas/source/graphicsItem/electricSvgItemCT.cpp +++ b/diagramCavas/source/graphicsItem/electricSvgItemCT.cpp @@ -45,28 +45,81 @@ void ElectricSvgItemCT::initial() void ElectricSvgItemCT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - if (!m_pRender || !m_pRender->isValid()) - return; - // 计算每个图形的宽度 qreal singleWidth = m_boundingRect.width() / 3.0; - // 绘制第一个图形 - if(_itemType == 1){ - QRectF rect1(m_boundingRect.x(), m_boundingRect.y(), singleWidth, m_boundingRect.height()); - m_pRender->render(painter, rect1); + if(_curMonitorStateEnable){ - // 绘制第二个图形 - QRectF rect2(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height()); - m_pRender->render(painter, rect2); + painter->setRenderHint(QPainter::Antialiasing); - // 绘制第三个图形 - QRectF rect3(m_boundingRect.x() + 2 * singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height()); - m_pRender->render(painter, rect3); + 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. 最终绘制 + //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){ - QRectF rect(m_boundingRect.x() + singleWidth, m_boundingRect.y(), singleWidth, m_boundingRect.height()); - m_pRender->render(painter, rect); + else{ + if (!m_pRender || !m_pRender->isValid()) + 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); + } } } diff --git a/diagramCavas/source/graphicsItem/electricSvgItemPT.cpp b/diagramCavas/source/graphicsItem/electricSvgItemPT.cpp index 0f82cfe..a1c7161 100644 --- a/diagramCavas/source/graphicsItem/electricSvgItemPT.cpp +++ b/diagramCavas/source/graphicsItem/electricSvgItemPT.cpp @@ -32,9 +32,44 @@ ElectricSvgItemPT* ElectricSvgItemPT::clone() const void ElectricSvgItemPT::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - if (!m_pRender || !m_pRender->isValid()) - return; - m_pRender->render(painter, m_boundingRect); + if(_curMonitorStateEnable){ + + 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() diff --git a/diagramCavas/source/graphicsItem/graphicsBaseItem.cpp b/diagramCavas/source/graphicsItem/graphicsBaseItem.cpp index 3a40609..655a377 100644 --- a/diagramCavas/source/graphicsItem/graphicsBaseItem.cpp +++ b/diagramCavas/source/graphicsItem/graphicsBaseItem.cpp @@ -52,7 +52,7 @@ GraphicsBaseItem::GraphicsBaseItem(const GraphicsBaseItem& obj) } 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); _curMonitorState = monitorItemState::Normal; + _curMonitorStateEnable = false; } GraphicsProjectModelItem::GraphicsProjectModelItem(const GraphicsProjectModelItem& obj) @@ -507,6 +508,7 @@ GraphicsProjectModelItem::GraphicsProjectModelItem(const GraphicsProjectModelIte setRotation(obj.rotation()); _curMonitorState = monitorItemState::Normal; + _curMonitorStateEnable = false; } GraphicsProjectModelItem::~GraphicsProjectModelItem() diff --git a/diagramCavas/source/monitorDisplaySettingDlg.cpp b/diagramCavas/source/monitorDisplaySettingDlg.cpp index 40b450f..f8db9ff 100644 --- a/diagramCavas/source/monitorDisplaySettingDlg.cpp +++ b/diagramCavas/source/monitorDisplaySettingDlg.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "projectModelManager.h" #include "projectIconSelectionDlg.h" @@ -27,8 +28,8 @@ void MonitorDisplaySettingDlg::initial() connect(ui->btn_save,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onSaveClicked); connect(ui->btn_cancel,&QPushButton::clicked,this,&MonitorDisplaySettingDlg::onCancelClicked); - connect(ui->cb_type,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onTypeChanged); - connect(ui->cb_state,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onStateChanged); + connect(ui->cb_type,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onDeviceComboBoxChanged); + connect(ui->cb_state,&QComboBox::currentTextChanged,this,&MonitorDisplaySettingDlg::onStateComboBoxChanged); connect(ui->btn_selectColor, &QPushButton::clicked, this, [this]() { QColor newColor = QColorDialog::getColor(_curColor, this, "选择颜色"); @@ -41,7 +42,7 @@ void MonitorDisplaySettingDlg::initial() ui->btn_selectColor->setText(newColor.name()); // 触发预览更新 - if(_curType.notEmpty() && _curState.notEmpty()){ + if(_curType.isValid() && _curState.isValid()){ _tempSetting[_curType][_curState].sColor = _curColor.name(); ui->content->setColors(_curColor); } @@ -56,18 +57,33 @@ void MonitorDisplaySettingDlg::showDlg() { show(); _tempSetting = _parent->getModelController()->getMonitorDisplaySetting(); + ui->cb_state->blockSignals(true); + ui->cb_type->blockSignals(true); ui->cb_type->clear(); ui->cb_state->clear(); + ui->cb_state->blockSignals(false); + ui->cb_type->blockSignals(false); for(auto iter = _tempSetting.begin();iter != _tempSetting.end();++iter){ 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() { - saveSetting(_curType,_curState); + if (validateCurrentDeviceState()) { + if (!saveCurrentSettingsWithIcon()) { + QMessageBox::warning(this, "Warning", "Failed to save current settings"); + } + } _parent->getModelController()->getMonitorDisplaySetting() = _tempSetting; + _parent->getModelController()->updateMonitorDisplay(); hide(); } @@ -96,22 +112,50 @@ void MonitorDisplaySettingDlg::onCheckboxToggled(bool val) void MonitorDisplaySettingDlg::onIconSelectClicked() { - if(!_curMeta.isEmpty() && !_curModel.isEmpty()){ - 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); + // if(!_curMeta.isEmpty() && !_curModel.isEmpty()){ + // 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)); - ui->content->setSvgFile(selectedSVG); + // ui->btn_selectIcon->setIcon(QIcon(pixmap)); + // 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; } } @@ -119,80 +163,59 @@ void MonitorDisplaySettingDlg::onIconSelectClicked() } } -void MonitorDisplaySettingDlg::onTypeChanged(const QString& str) +void MonitorDisplaySettingDlg::onDeviceComboBoxChanged(const QString& str) { - /*saveSetting(_curType,_curState); - ui->cb_state->clear(); - monitorItemTypeStruct keyType; - keyType.sTag = ui->cb_type->currentData().toString(); - keyType.sName = str; - QMap 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; - } + if (str.isEmpty()) { + return; } - _curType = keyType; - onStateChanged(ui->cb_state->currentText());*/ - //monitorItemStateStruct keyState; - //keyState.sState = ui->cb_state->currentText(); - //loadSetting(_curType,ui->cb_state->currentText()); - // 1. 保存当前设备类型的设置 - saveSetting(_curType, _curState); + // 1. 保存当前设备的非图标数据 + if (_curType.isValid() && _curState.isValid()) { + saveCurrentSettingsWithIcon(); + clearIconDisplay(); + } - // 2. 清空状态下拉框 - ui->cb_state->clear(); + // 2. 构建新设备 + monitorItemTypeStruct newType; + newType.sTag = ui->cb_type->currentData().toString(); + newType.sName = str; - // 3. 构建新的设备类型键值 - monitorItemTypeStruct keyType; - keyType.sTag = ui->cb_type->currentData().toString(); - keyType.sName = str; + if (!newType.isValid()) { + return; + } - // 4. 获取新设备类型对应的状态列表 - QMap mapInfo = _tempSetting.value(keyType); - - // 5. 如果新设备类型没有状态数据,直接返回 - if (mapInfo.isEmpty()) { - _curType = keyType; - // 清空当前状态相关显示 + // 3. 检查新设备是否存在 + if (!_tempSetting.contains(newType)) { + _curType = newType; + _curState = monitorItemStateStruct(); clearStateDisplay(); return; } - // 6. 填充状态下拉框 - QString firstState; // 记录第一个状态,用于后续加载 - for (auto iter = mapInfo.begin(); iter != mapInfo.end(); ++iter) { - QString stateName = iter.key().sState; - int stateValue = static_cast(iter.key().eState); + // 4. 清空状态下拉框 + ui->cb_state->blockSignals(true); + ui->cb_state->clear(); + ui->cb_state->blockSignals(false); - ui->cb_state->addItem(stateName, stateValue); - - // 记录第一个状态 - if (firstState.isEmpty()) { - firstState = stateName; - } - - // 更新元数据(如果有变化) - if (_curMeta != iter->sMeta) { - _curMeta = iter->sMeta; - } + // 5. 填充新设备的状态 + auto& stateMap = _tempSetting[newType]; + for (auto iter = stateMap.begin(); iter != stateMap.end(); ++iter) { + ui->cb_state->addItem(iter.key().sState, static_cast(iter.key().eState)); } - // 7. 更新当前设备类型 - _curType = keyType; + // 6. 更新当前设备 + _curType = newType; - // 8. 加载第一个状态的设置 - if (!firstState.isEmpty()) { - // 设置下拉框当前项为第一个状态 - ui->cb_state->setCurrentIndex(0); - // 触发状态变化处理 - onStateChanged(firstState); + // 7. 加载第一个状态 + if (ui->cb_state->count() > 0) { + loadFirstStateSafely(); + } else { + _curState = monitorItemStateStruct(); + clearStateDisplay(); } } -void MonitorDisplaySettingDlg::onStateChanged(const QString& str) +void MonitorDisplaySettingDlg::onStateComboBoxChanged(const QString& str) { /*if(_tempSetting.contains(_curType)){ monitorItemStateStruct keyState; @@ -209,120 +232,228 @@ void MonitorDisplaySettingDlg::onStateChanged(const QString& str) loadSetting(_curType,_curState); } }*/ - // 1. 检查当前设备类型是否存在 - if (!_tempSetting.contains(_curType)) { + + if (str.isEmpty() || str == _curState.sState) { return; } - // 2. 检查状态是否为空 - if (str.isEmpty()) { - return; + // 1. 保存当前状态的完整数据(包括图标) + if (_curType.isValid() && _curState.isValid()) { + saveCurrentSettingsWithIcon(); // 保存完整数据 } - // 3. 构建状态键值 - monitorItemStateStruct keyState; - keyState.sState = str; - - // 4. 从下拉框获取状态枚举值(添加安全检查) + // 2. 获取新状态 QVariant stateData = ui->cb_state->currentData(); if (!stateData.isValid()) { return; } - bool ok = false; - int stateValue = stateData.toInt(&ok); - if (!ok) { - return; - } + monitorItemStateStruct newState; + newState.sState = str; + newState.eState = static_cast(stateData.toInt()); - keyState.eState = monitorItemState(stateValue); + // 3. 更新当前状态 + _curState = newState; - // 5. 检查状态是否存在 - 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; + // 4. 加载新状态设置 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); - if(setting.bEnable){ - ui->btn_selectColor->setEnabled(true); - ui->btn_selectIcon->setEnabled(true); - ui->sb_width->setEnabled(true); - ui->sb_height->setEnabled(true); - ui->cb_effect->setEnabled(true); - } - else{ - 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); - } + + // 设置控件可用性 + bool enabled = setting.bEnable; + ui->btn_selectColor->setEnabled(enabled); + ui->btn_selectIcon->setEnabled(enabled); + ui->sb_width->setEnabled(enabled); + ui->sb_height->setEnabled(enabled); + ui->cb_effect->setEnabled(enabled); + + // 更新颜色 _curColor = QColor(setting.sColor); - // 更新按钮显示 - QPixmap pixmap(16, 16); - pixmap.fill(_curColor); - ui->btn_selectColor->setIcon(QIcon(pixmap)); + if (!_curColor.isValid()) { + _curColor = Qt::black; + } + + QPixmap colorPixmap(16, 16); + colorPixmap.fill(_curColor); + ui->btn_selectColor->setIcon(QIcon(colorPixmap)); ui->btn_selectColor->setText(_curColor.name()); - QSvgRenderer renderer(setting.bytPicture); - QPixmap pixSvg(32, 32); - pixmap.fill(Qt::transparent); - QPainter painter(&pixSvg); - renderer.render(&painter); + // 更新图标 + if (!setting.bytPicture.isEmpty()) { + QSvgRenderer renderer(setting.bytPicture); + if (renderer.isValid()) { + 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->setColors(_curColor); + ui->content->setSvgFile(setting.bytPicture); + } + } else { + ui->btn_selectIcon->setIcon(QIcon()); + ui->content->clearSvg(); + } + // 更新尺寸 ui->sb_width->setValue(setting.nWidth); 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()){ - auto& setting = _tempSetting[type][state]; - 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(); + if (!_curType.isValid() || !_curState.isValid()) { + return false; } -} -void MonitorDisplaySettingDlg::updatePreview() -{ - ui->content->update(); + if (!_tempSetting.contains(_curType) || !_tempSetting[_curType].contains(_curState)) { + return false; + } + + 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() { ui->checkBox_custom->setChecked(false); - // 可以添加其他需要清空的UI元素 - _curState = monitorItemStateStruct(); // 清空当前状态 - _curModel = QString(); // 清空当前模型 - _curMeta = QString(); // 清空元数据 + 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); + + // 清空图标显示 + 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(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); +} + diff --git a/diagramCavas/source/monitorItemPreviewDlg.cpp b/diagramCavas/source/monitorItemPreviewDlg.cpp index b03e11d..18c920e 100644 --- a/diagramCavas/source/monitorItemPreviewDlg.cpp +++ b/diagramCavas/source/monitorItemPreviewDlg.cpp @@ -30,29 +30,54 @@ void MonitorItemPreviewDlg::setColors(const QColor &color) update(); } +void MonitorItemPreviewDlg::clearSvg() +{ + QByteArray emptySvg = ""; + _curSvg.clear(); + m_renderer.load(emptySvg); + m_curDeviceType.clear(); +} + void MonitorItemPreviewDlg::paintEvent(QPaintEvent *) { - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); + if(m_curDeviceType == "cable"){ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); - // 1. 先将SVG渲染到一个透明图像上作为遮罩 - QImage maskImage(size(), QImage::Format_ARGB32); - maskImage.fill(Qt::transparent); + // 设置线宽 + int lineWidth = 3; + painter.setPen(QPen(m_Color, lineWidth)); - QPainter maskPainter(&maskImage); - m_renderer.render(&maskPainter); - maskPainter.end(); + // 定义折线的各个顶点 + QPolygon polyline; + 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的非透明区域显示 - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + // 1. 先将SVG渲染到一个透明图像上作为遮罩 + QImage maskImage(size(), QImage::Format_ARGB32); + maskImage.fill(Qt::transparent); - 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); + QPainter maskPainter(&maskImage); + m_renderer.render(&maskPainter); + maskPainter.end(); + + // 2. 使用目标颜色填充,但只在SVG的非透明区域显示 + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + + 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); + } } } }