add HMI custom type plugin

This commit is contained in:
baiYue 2026-04-01 16:39:23 +08:00
parent 9a6ce08b82
commit f0c7a7a9e6
29 changed files with 1118 additions and 138 deletions

View File

@ -75,7 +75,6 @@ set(H_HEADER_FILES
common/include/pluginCommon/iCanvasItem.h
common/include/pluginCommon/iPlugin.h
common/include/pluginCommon/iShapeFactory.h
common/include/pluginCommon/iPluginAdapter.h
common/core_model/types.h
common/core_model/topology.h
@ -113,6 +112,8 @@ set(CPP_SOURCE_FILES
common/source/extraPropertyManager.cpp
common/core_model/types.cpp
common/source/iPlugin.cpp
)
set(UI_FILES
ui/mainwindow.ui
@ -193,3 +194,4 @@ target_link_libraries(DiagramDesigner PRIVATE diagramCavas diagramUtils diagramC
file(COPY setting.xml DESTINATION "${CMAKE_BINARY_DIR}/${dd_PlatformDir}/bin")
add_subdirectory(customTypePlugin)

View File

@ -286,4 +286,12 @@ struct MonitorItemDisplayInfo //监控模式显示信息
sModel = json["sModel"].toString();
}
};
struct PluginTypeInfo //插件的类型信息
{
QString shapeName; //插件中的类型名
int baseType; //基础类型
QString modelName; //工程模名
};
#endif

View File

@ -14,6 +14,8 @@ public:
// 基本信息
virtual QString typeId() const = 0;
virtual QString displayName() const = 0;
virtual int baseType() const = 0; //基础分类
virtual bool containSvg() const = 0;
// 几何属性
virtual QRectF bounds() const = 0;
@ -23,7 +25,7 @@ public:
virtual void draw(QPainter *painter, const QRectF &rect) = 0;
// 属性管理
virtual QVariant property(const QString &key) const = 0;
virtual QVariant getProperty(const QString &key) const = 0;
virtual void setProperty(const QString &key, const QVariant &value) = 0;
signals:

View File

@ -4,18 +4,19 @@
#include <QtPlugin>
#include <QIcon>
#include "iCanvasItem.h"
//#include "export.hpp"
// 形状描述
struct ShapeDescriptor {
QString id; // 形状标识符
QString name; // 显示名称
QString category; // 分类
int category; // 分类(基础类型)
QString iconPath; // 图标路径
QVariantMap defaults; // 默认属性
};
// 插件描述
struct PluginDescriptor {
struct PluginDescriptor {
QString id; // 插件ID
QString name; // 插件名称
QString version; // 版本
@ -48,4 +49,4 @@ public:
virtual QIcon shapeIcon(const QString &shapeId) const = 0;
};
Q_DECLARE_INTERFACE(IPlugin, "com.canvas.plugin/1.0")
Q_DECLARE_INTERFACE(IPlugin, "com.diagramDesigner.plugin/1.0")

View File

@ -0,0 +1 @@
#include "pluginCommon/iPlugin.h"

View File

@ -0,0 +1,59 @@
project(customTypePlugin)
set(CUSTOMTYPEPLUGIN_HEADER_FILES
include/customTypePlugin.h
include/reactorItem.h
../common/include/compiler.hpp
../common/include/export.hpp
../common/include/operatingSystem.hpp
../common/include/pluginCommon/iPlugin.h
../common/include/pluginCommon/iCanvasItem.h
)
set(CUSTOMTYPEPLUGIN_SOURCE_FILES
source/customTypePlugin.cpp
source/reactorItem.cpp
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_library(customTypePlugin SHARED
MANUAL_FINALIZATION
${CUSTOMTYPEPLUGIN_HEADER_FILES}
${CUSTOMTYPEPLUGIN_SOURCE_FILES}
)
else()
add_library(customTypePlugin SHARED
${CUSTOMTYPEPLUGIN_HEADER_FILES}
${CUSTOMTYPEPLUGIN_SOURCE_FILES}
)
endif()
target_link_libraries(customTypePlugin PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(customTypePlugin PRIVATE Qt6::Xml)
target_link_libraries(customTypePlugin PRIVATE Qt6::Network)
#target_link_libraries(customTypePlugin PRIVATE Qt6::Sql ${PostgreSQL_LIBRARIES})
option(BUILD_SHARED_LIBS "Build as shared library" ON)
target_include_directories(customTypePlugin PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(customTypePlugin
PUBLIC
DIAGRAM_DESIGNER_SHARED
PRIVATE
DIAGRAM_DESIGNER_EXPORTS
QT_PLUGIN
)
set_target_properties(customTypePlugin PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${dd_PlatformDir}/bin/plugins"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${dd_PlatformDir}/bin/plugins"
)

View File

@ -0,0 +1,10 @@
{
"pluginId": "com.diagramDesigner.plugin/1.0",
"name": "电抗器插件",
"version": "1.0.0",
"author": "by",
"description": "自定义电抗器类型",
"license": "MIT",
"minApiVersion": "1.0.0",
"dependencies": []
}

View File

@ -0,0 +1,32 @@
// customTypePlugin.h
#pragma once
#include "pluginCommon/iPlugin.h"
#include "reactorItem.h"
#include "export.hpp"
#include <QObject>
class DIAGRAM_DESIGNER_PUBLIC CustomTypePlugin : public IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.diagramDesigner.plugin/1.0" FILE "customType.json")
Q_INTERFACES(IPlugin)
public:
explicit CustomTypePlugin(QObject *parent = nullptr);
virtual ~CustomTypePlugin();
// IPlugin接口实现
PluginDescriptor descriptor() const override;
QList<ShapeDescriptor> shapes() const override;
ICanvasItem* createShape(const QString &shapeId) override;
bool initialize() override;
void shutdown() override;
QIcon shapeIcon(const QString &shapeId) const override;
private:
QIcon m_reactorIcon;
QIcon loadIcon(const QString &path) const;
QIcon createDefaultIcon() const;
};

View File

@ -0,0 +1,34 @@
// reactorItem.h
#pragma once
#include "pluginCommon/iCanvasItem.h"
#include <QPainter>
class ReactorItem : public ICanvasItem
{
Q_OBJECT
public:
explicit ReactorItem(QObject *parent = nullptr);
// ICanvasItem接口
QString typeId() const override { return "reactor"; }
QString displayName() const override { return "电抗器"; }
int baseType() const override {return 18;}
bool containSvg() const override {return true;}
QRectF bounds() const override;
void setBounds(const QRectF &rect) override;
void draw(QPainter *painter, const QRectF &rect) override;
QVariant getProperty(const QString &key) const override;
void setProperty(const QString &key, const QVariant &value) override;
private:
QRectF m_bounds = QRectF(-30, -30, 60, 60);
QColor m_fillColor = QColor(100, 150, 255, 200);
QColor m_borderColor = Qt::black;
int m_borderWidth = 2;
int m_cornerRadius = 0;
};

View File

@ -0,0 +1,145 @@
// customTypePlugin.cpp
#include "customTypePlugin/include/customTypePlugin.h"
#include "customTypePlugin/include/reactorItem.h"
#include <QDebug>
#include <QFile>
#include <QDir>
#include <QPixmap>
#include <QPainter>
CustomTypePlugin::CustomTypePlugin(QObject *parent)
: IPlugin(parent)
{
qDebug() << "CustomTypePlugin constructor";
}
CustomTypePlugin::~CustomTypePlugin()
{
qDebug() << "CustomTypePlugin destructor";
}
PluginDescriptor CustomTypePlugin::descriptor() const
{
PluginDescriptor desc;
desc.id = "com.diagramDesigner.plugin.customType";
desc.name = "自定义类型";
desc.version = "1.0.0";
desc.author = "by";
desc.description = "自定义类型插件";
return desc;
}
QList<ShapeDescriptor> CustomTypePlugin::shapes() const
{
ShapeDescriptor reactor;
reactor.id = "reactor";
reactor.name = "电抗器";
reactor.category = 18; //电抗器临时定为18
reactor.iconPath = ":/rectangle/rectangle.png";
reactor.defaults = {
{"width", 100.0},
{"height", 60.0},
{"fillColor", QColor(100, 150, 255, 180)},
{"borderColor", QColor(0, 0, 0, 200)},
{"borderWidth", 2.0},
{"cornerRadius", 0.0}
};
return {reactor};
}
ICanvasItem* CustomTypePlugin::createShape(const QString &shapeId)
{
if (shapeId == "reactor") {
ReactorItem *item = new ReactorItem;
// 应用默认属性
ShapeDescriptor desc = shapes().first(); // 电抗器描述
for (auto it = desc.defaults.begin(); it != desc.defaults.end(); ++it) {
item->setProperty(it.key(), it.value());
}
return item;
}
qWarning() << "Unknown shape ID:" << shapeId;
return nullptr;
}
bool CustomTypePlugin::initialize()
{
qDebug() << "Rectangle plugin initializing...";
// 每个实例加载自己的图标
m_reactorIcon = loadIcon(":/rectangle/rectangle.png");
// 如果资源中没有,创建默认图标
if (m_reactorIcon.isNull()) {
m_reactorIcon = createDefaultIcon();
}
qDebug() << "Rectangle plugin initialized successfully";
return true;
}
void CustomTypePlugin::shutdown()
{
qDebug() << "Rectangle plugin shutting down...";
// 清理资源
m_reactorIcon = QIcon();
qDebug() << "Rectangle plugin shutdown complete";
}
QIcon CustomTypePlugin::shapeIcon(const QString &shapeId) const
{
QString iconPath;
if (shapeId == "reactor") {
iconPath = ":/custom/reactor.png";
} else {
return QIcon();
}
// 尝试加载图标
QIcon icon = loadIcon(iconPath);
if (!icon.isNull()) {
return icon;
}
return createDefaultIcon();
}
QIcon CustomTypePlugin::loadIcon(const QString &path) const
{
if (QFile::exists(path)) {
return QIcon(path);
}
return QIcon();
}
QIcon CustomTypePlugin::createDefaultIcon() const
{
QPixmap pixmap(32, 32);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing, true);
// 绘制背景
painter.setBrush(QBrush(QColor(240, 240, 240)));
painter.setPen(Qt::NoPen);
painter.drawRoundedRect(1, 1, 30, 30, 4, 4);
// 绘制矩形
QRectF rect(6, 6, 20, 20);
painter.setBrush(QBrush(QColor(100, 150, 255, 180)));
painter.setPen(QPen(QColor(0, 0, 0, 200), 1.5));
painter.drawRect(rect);
return QIcon(pixmap);
}

View File

@ -0,0 +1,150 @@
// plugins/rectangle/RectangleItem.cpp
#include "customTypePlugin/include/reactorItem.h"
#include <QDebug>
#include <QVariant>
ReactorItem::ReactorItem(QObject *parent)
{
}
QRectF ReactorItem::bounds() const
{
return m_bounds;
}
void ReactorItem::setBounds(const QRectF &rect)
{
if (m_bounds != rect && rect.isValid()) {
m_bounds = rect;
emit boundsChanged(rect);
}
}
void ReactorItem::draw(QPainter *painter, const QRectF &rect)
{
if (!painter) return;
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
// 创建画笔
QPen pen;
if (m_borderWidth > 0) {
pen.setColor(m_borderColor);
pen.setWidthF(m_borderWidth);
pen.setStyle(Qt::SolidLine);
} else {
pen.setStyle(Qt::NoPen);
}
// 创建画刷
QBrush brush(m_fillColor);
painter->setPen(pen);
painter->setBrush(brush);
// 绘制矩形
if (m_cornerRadius > 0) {
painter->drawRoundedRect(rect, m_cornerRadius, m_cornerRadius);
} else {
painter->drawRect(rect);
}
// 绘制尺寸标签(可选)
if (rect.width() > 40 && rect.height() > 30) {
painter->save();
painter->setPen(Qt::darkGray);
QFont font = painter->font();
font.setPointSize(8);
painter->setFont(font);
QString sizeText = QString("%1×%2").arg(rect.width()).arg(rect.height());
painter->drawText(rect.adjusted(2, 2, -2, -2),
Qt::AlignLeft | Qt::AlignTop,
sizeText);
painter->restore();
}
painter->restore();
}
QVariant ReactorItem::getProperty(const QString &key) const
{
if (key == "width") return m_bounds.width();
if (key == "height") return m_bounds.height();
if (key == "x") return m_bounds.x();
if (key == "y") return m_bounds.y();
if (key == "fillColor") return m_fillColor;
if (key == "borderColor") return m_borderColor;
if (key == "borderWidth") return m_borderWidth;
if (key == "cornerRadius") return m_cornerRadius;
return QVariant();
}
void ReactorItem::setProperty(const QString &key, const QVariant &value)
{
bool geometryChanged = false;
QRectF newBounds = m_bounds;
if (key == "width" && value.canConvert<double>()) {
double w = value.toDouble();
if (w > 0 && w != newBounds.width()) {
newBounds.setWidth(w);
geometryChanged = true;
}
}
else if (key == "height" && value.canConvert<double>()) {
double h = value.toDouble();
if (h > 0 && h != newBounds.height()) {
newBounds.setHeight(h);
geometryChanged = true;
}
}
else if (key == "x" && value.canConvert<double>()) {
double x = value.toDouble();
if (x != newBounds.x()) {
newBounds.moveLeft(x);
geometryChanged = true;
}
}
else if (key == "y" && value.canConvert<double>()) {
double y = value.toDouble();
if (y != newBounds.y()) {
newBounds.moveTop(y);
geometryChanged = true;
}
}
else if (key == "fillColor" && value.canConvert<QColor>()) {
QColor color = value.value<QColor>();
if (color != m_fillColor) {
m_fillColor = color;
emit propertyChanged(key, value);
}
}
else if (key == "borderColor" && value.canConvert<QColor>()) {
QColor color = value.value<QColor>();
if (color != m_borderColor) {
m_borderColor = color;
emit propertyChanged(key, value);
}
}
else if (key == "borderWidth" && value.canConvert<double>()) {
double width = value.toDouble();
if (width >= 0 && width != m_borderWidth) {
m_borderWidth = width;
emit propertyChanged(key, value);
}
}
else if (key == "cornerRadius" && value.canConvert<double>()) {
double radius = value.toDouble();
if (radius >= 0 && radius != m_cornerRadius) {
m_cornerRadius = radius;
emit propertyChanged(key, value);
}
}
if (geometryChanged && newBounds.isValid()) {
m_bounds = newBounds;
}
}

View File

@ -64,6 +64,7 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/graphicsItem/pluginItemFactory.h
include/graphicsItem/pluginItemWrapper.h
include/graphicsItem/pluginSvgItemWrapper.h
include/graphicsItem/functionModelItem/electricFunctionModelConnectLineItem.h
include/graphicsItem/functionModelItem/electricFunctionModelPortItem.h
@ -193,6 +194,7 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/graphicsItem/pluginItemFactory.cpp
source/graphicsItem/pluginItemWrapper.cpp
source/graphicsItem/pluginSvgItemWrapper.cpp
source/graphicsItem/functionModelItem/electricFunctionModelConnectLineItem.cpp
source/graphicsItem/functionModelItem/electricFunctionModelPortItem.cpp

View File

@ -7,6 +7,7 @@
#include "common/core_model/topology.h"
#include "common/core_model/types.h"
#include "common/core_model/diagram.h"
#include "common/frontend/monitor_item.h"
#include "export.hpp"
QT_BEGIN_NAMESPACE
@ -27,6 +28,8 @@ class StructDataPreviewDlg;
class ExtraPropertyManager;
class DataSourceDlg;
class CreateHMIdlg;
class PluginManager;
class PluginItemFactory;
class DIAGRAM_DESIGNER_PUBLIC DiagramCavas : public QMdiArea
{
@ -43,6 +46,7 @@ public:
void passRecommmandHttpData(HttpRecommandInfo); //传递推荐列表数据
DiagramConnectSetting* getConnectSettingDlg() {return _connectSetting;}
ExtraPropertyManager* getExtraPropertyManager() {return _extraPropertyManager;}
QMap<QString,PluginTypeInfo> getPluginShapeInfo() {return m_pluginInfo;}
public:
void initial();
signals:
@ -115,6 +119,9 @@ protected:
private:
void removePanel(PowerEntity*);
void calculateLauncherVisible();
bool loadPluginConfig(const QString&); //载入插件配置文件
bool parsePluginConfig(const QJsonObject& root); //解析插件配置文件
private:
QMap<QString,QPair<MonitorPanel*,QMdiSubWindow*>> m_mapMonitorPanel; //监控时panel
int _pageIndex;
@ -126,6 +133,10 @@ private:
StructDataPreviewDlg* _structDataPreviewDlg;
ExtraPropertyManager* _extraPropertyManager;
CreateHMIdlg* _createHMIDlg;
PluginManager* m_pluginManager; //插件管理类
PluginItemFactory* m_itemFactory; //插件图元工厂类
QMap<QString,PluginTypeInfo> m_pluginInfo; //插件对照信息
};
#endif

View File

@ -128,6 +128,8 @@ public:
int customImageRefExist(QUuid uid,QByteArray hash256);
void updateHMIRef(QUuid hmiId,QString model,QByteArray hash256,int slot); //更新img引用
void updateHMICustomRef(QUuid hmiId,QString model,QUuid itemId,QByteArray hash256); //更新customImg引用
void updatePannelProperty(); //更新界面的属性信息
/************************数据显示*************************/
void setCurItemPropertyDlg(ItemPropertyDlg* p) {m_curPropertyDlg = p;}
ItemPropertyDlg* getCurItemPropertyDlg() {return m_curPropertyDlg;}

View File

@ -9,9 +9,8 @@ class ElectricFunctionModelSvgItem :public GraphicsFunctionModelItem
public:
Q_PROPERTY(QFileInfo Image READ getImage_1 WRITE setImage_1)
public:
ElectricFunctionModelSvgItem(const QRect &rect, bool genNewPort = true,QGraphicsItem *parent = 0); //genNewPort生成新接线点
ElectricFunctionModelSvgItem(const QRect &rect,QGraphicsItem *parent = 0);
virtual ~ElectricFunctionModelSvgItem();
void resize(int,double, double, const QPointF&) override;
void updateCoordinate() override;
void move(const QPointF&) override;
virtual void loadSvg(){};

View File

@ -0,0 +1,53 @@
//pluginSvgItemWrapper.h
#pragma once
#include "functionModelItem/electricFunctionModelSvgItem.h"
#include "pluginCommon/iCanvasItem.h"
#include <QObject>
// 内部包装器,不暴露给外部
class PluginSvgItemWrapper : public ElectricFunctionModelSvgItem
{
Q_OBJECT
public:
explicit PluginSvgItemWrapper(ICanvasItem *pluginItem, QGraphicsItem *parent = nullptr);
virtual ~PluginSvgItemWrapper();
virtual void setImage_1(QFileInfo) override;
// 克隆
virtual ElectricFunctionModelSvgItem* clone() const override;
// 绘图
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
virtual QRectF boundingRect() const override;
virtual QPainterPath shape() const override;
// 几何操作
virtual void updateCoordinate() override;
virtual void resize(int handle, double dx, double dy, const QPointF &pos) override;
virtual void move(const QPointF &delta) override;
// 获取插件项
ICanvasItem* pluginItem() const;
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
private:
ICanvasItem *m_pluginItem = nullptr;
QRectF m_cachedBounds;
void updateCache();
void connectSignals();
QVariantMap saveState() const;
bool loadStateIntoPluginItem(ICanvasItem *pluginItem, const QVariantMap &state) const;
void copyPropertiesFrom(const PluginSvgItemWrapper *source);
private slots:
void onPluginBoundsChanged(const QRectF &newBounds);
void onPluginPropertyChanged(const QString &key, const QVariant &value);
};

View File

@ -4,6 +4,7 @@
#include <QStandardItem>
#include <QLibrary>
#include <QMetaMethod>
#include <QApplication>
#include "monitorPanel.h"
#include "diagramCavas.h"
#include "dataBase.h"
@ -23,11 +24,15 @@
#include "structDataPreviewDlg.h"
#include "extraPropertyManager.h"
#include "createHMIdlg.h"
#include "pluginManager.h"
#include "graphicsItem/pluginItemFactory.h"
#include "QQuickDetailsViewMananger.h"
#include "propertyType/propertyTypeCustomization_DataSourceType.h"
#include "propertyType/dataSourceType.h"
#include "basePannelPropertyProxy.h"
DiagramCavas::DiagramCavas(QWidget *parent)
: QMdiArea(parent)
,_cornerButton(nullptr)
@ -37,6 +42,8 @@ DiagramCavas::DiagramCavas(QWidget *parent)
,_structDataPreviewDlg(nullptr)
,_extraPropertyManager(nullptr)
,_createHMIDlg(nullptr)
,m_pluginManager(nullptr)
,m_itemFactory(nullptr)
{
_pageIndex = 0;
}
@ -155,6 +162,17 @@ void DiagramCavas::initial()
_createHMIDlg = new CreateHMIdlg(this);
connect(_createHMIDlg,&CreateHMIdlg::createHMI,this,&DiagramCavas::onSignal_createHMIClicked);
updateHMIlstFromDB();
loadPluginConfig(QCoreApplication::applicationDirPath()+"/pluginConfig.json"); //加载plugin关联信息
m_pluginManager = PluginManager::instance();
//创建Canvas项工厂
m_itemFactory = PluginItemFactory::instance();
m_itemFactory->setPluginManager(m_pluginManager);
//加载插件
QString pluginsDir = QApplication::applicationDirPath() + "/plugins";
m_pluginManager->addPluginDirectory(pluginsDir);
m_pluginManager->loadAllPlugins(pluginsDir);
}
void DiagramCavas::onSignal_addDrawingPanel(PowerEntity* pItem,DiagramMode mode,QString parent)
@ -257,6 +275,7 @@ void DiagramCavas::onSignal_loadMonitor(PowerEntity* p)
{
m_mapMonitorPanel[p->name()].first->show();
}
onTargetSelected(m_mapMonitorPanel[p->name()].first->getPropertyProxy());
}
void DiagramCavas::runPage(const QString sName)
@ -477,6 +496,51 @@ void DiagramCavas::calculateLauncherVisible()
}
}
bool DiagramCavas::loadPluginConfig(const QString& configPath)
{
QFile file(configPath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Cannot open config file:" << configPath;
return false;
}
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
if (doc.isNull() || !doc.isObject()) {
qWarning() << "Invalid JSON config";
return false;
}
return parsePluginConfig(doc.object());
}
bool DiagramCavas::parsePluginConfig(const QJsonObject& root)
{
if (!root.contains("shapes")) {
qWarning() << "Missing 'shapes' key";
return false;
}
QJsonArray items = root["shapes"].toArray();
for (const QJsonValue& itemVal : items) {
QJsonObject itemObj = itemVal.toObject();
int type = itemObj["type"].toInt();
QString shapeName = itemObj["shapeName"].toString();
QString modelName = itemObj["modelName"].toString();
// 解析枚举类型
PluginTypeInfo info;
info.baseType = type;
info.shapeName = shapeName;
info.modelName = modelName;
m_pluginInfo[shapeName] = info;
}
qDebug() << "Loaded" << m_pluginInfo.size() << "shapes types from config";
return true;
}
void DiagramCavas::resizeEvent(QResizeEvent* event)
{
if(_cornerButton)
@ -527,6 +591,7 @@ void DiagramCavas::onSignal_createHMIClicked(QString sHMI,QString sStructPage,in
QJsonObject context = DataBase::GetInstance()->getMonitorContextByTag(sStructPage);
m_mapMonitorPanel[sHMI].first->loadNodes(context); //加载系统图结构
onSignal_createHMI(sHMI,id);
onTargetSelected(m_mapMonitorPanel[sHMI].first->getPropertyProxy());
}
void DiagramCavas::onSignal_updateCurItems(QList<HierarchyItem> lst,bool refresh)

View File

@ -22,6 +22,9 @@
#include "graphicsItem/functionModelItem/electricFunctionModelSvgItemImage.h"
#include "graphicsItem/functionModelItem/electricFunctionModelItemText.h"
#include "pluginManager.h"
#include "graphicsItem/pluginItemFactory.h"
#include "graphicsItem/itemPort.h"
#include "designerScene.h"
#include "dataBase.h"
@ -261,8 +264,9 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
pro = mapData.value(id);
if(pro)
{
int type = pro->graphicsType();
if(type == GIT_link) //连线对象外部处理
int type = pro->type();
//int type = pro->graphicsType();
if(type == 8) //GIT_link 电缆对象外部处理
return QString("err");
QString sMeta = pro->metaModelName();
QString sProModel = pro->modelName();
@ -276,7 +280,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
double dX = 0.0;
double dY = 0.0;
if(type == GIT_itemRect)
if(type == 3) //GIT_itemRect断路器
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -303,7 +307,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
QJsonArray portArr = pro->context()["port"].toArray();
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_node)
else if(type == 0) //GIT_node 节点(暂定为0)
{
auto pNode = new ElectricFunctionModelPortItem();
pNode->setItemType(GIT_node);
@ -312,7 +316,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
QJsonArray portArr = pro->context()["port"].toArray();
addPortsToItem_json(p_movable,portArr,item);
}
else if(type == GIT_bus)
else if(type == 1) //GIT_bus 母线
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -340,7 +344,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
QJsonArray portArr = pro->context()["port"].toArray();
addPortsToItem_json(p_movable,portArr,item);
}
else if(type == GIT_ctGroup)
else if(type == 4) //GIT_ctGroup ct组
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -393,7 +397,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
}
}
else if(type == GIT_ptGroup)
else if(type == 5) //GIT_ptGroup pt组
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -447,7 +451,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
}
}
}
else if(type == GIT_DS)
else if(type == 9) //GIT_DS 隔离开关
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -475,7 +479,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_ES)
else if(type == 6) //GIT_ES 接地开关
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -503,7 +507,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_FES)
else if(type == 7) //GIT_FES 快速接地开关
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -531,7 +535,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_DTEDS)
else if(type == 10) //GIT_DTEDS 双掷接地隔离开关
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -559,7 +563,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_PI)
else if(type == 11) //GIT_PI 带点指示器
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -587,7 +591,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_LA)
else if(type == 12) //GIT_LA 避雷器
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -615,7 +619,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_cableTer)
else if(type == 13) //GIT_cableTer 电缆出线套筒
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -643,7 +647,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_cableEnd)
else if(type == 14) //GIT_cableEnd 电缆端
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -671,7 +675,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_2wTransformer)
else if(type == 15) //GIT_2wTransformer 两绕组变压器
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -699,7 +703,7 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_3wTransformer)
else if(type == 16) //GIT_3wTransformer 三绕组变压器
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
@ -727,6 +731,30 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else{ //其他基础类型,自定义
bool shapeExist = false;
PluginTypeInfo shapeInfo; //类型对照关系
auto mapPluginShapes = _cavas->getPluginShapeInfo();
for(auto& info:mapPluginShapes){
if(info.baseType == type){
shapeExist = true;
shapeInfo = info;
break;
}
}
if(shapeExist){
QStringList shapes = PluginManager::instance()->availableShapes();
if(shapes.contains(shapeInfo.shapeName)){ //实际插件中存在该类型
auto pluginItem = PluginItemFactory::instance()->createItem(shapeInfo.shapeName);
if(pluginItem){
item = pluginItem;
QJsonArray portArr = pro->context()["port"].toArray();
addPortsToItem_json(P_const,portArr,item);
}
}
}
}
if(item)
{
item->setItemId(id);
@ -2569,3 +2597,8 @@ void FixedPortsModel::updateHMICustomRef(QUuid hmiId,QString model,QUuid itemId,
_HMICustomImageRef.append(ref);
}
}
void FixedPortsModel::updatePannelProperty()
{
_cavas->onTargetSelected(_widget->getPropertyProxy());
}

View File

@ -5,7 +5,7 @@
#include <QSvgRenderer>
#include <QDebug>
ElectricFunctionModelSvgItem::ElectricFunctionModelSvgItem(const QRect &rect, bool autoGenPort,QGraphicsItem *parent)
ElectricFunctionModelSvgItem::ElectricFunctionModelSvgItem(const QRect &rect,QGraphicsItem *parent)
: GraphicsFunctionModelItem(parent),m_pRender(nullptr),m_pCustomRender(nullptr)
{
m_lastBoudingRect = rect;
@ -114,35 +114,6 @@ void ElectricFunctionModelSvgItem::paint(QPainter* painter, const QStyleOptionGr
}
}
void ElectricFunctionModelSvgItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{
switch (nHandle)
{
case H_left:
case H_right:
dSY = 1; //拖拽的是左点右点,为水平缩放,忽略垂直变化
break;
case H_top:
case H_bottom:
dSX = 1; //拖拽的是顶点底点,为垂直缩放,忽略水平变化
break;
default:
break;
}
QTransform trans;
//缩放是以图元原点(中心)位置为基准,所以每帧都先移动移动到想要的基准点,缩放之后再移回
trans.translate(basePoint.x(), basePoint.y());
trans.scale(dSX, dSY);
trans.translate(-basePoint.x(), -basePoint.y());
prepareGeometryChange();
m_boundingRect = trans.mapRect(m_lastBoudingRect);
m_dWidth = m_boundingRect.width();
m_dHeight = m_boundingRect.height();
updateHandles();
}
void ElectricFunctionModelSvgItem::move(const QPointF& point)
{
moveBy(point.x(), point.y());

View File

@ -1,6 +1,7 @@
// src/canvas/PluginItemFactory.cpp
#include "diagramCavas/include/graphicsItem/pluginItemFactory.h"
#include "include/graphicsItem/pluginItemWrapper.h"
#include "include/graphicsItem/pluginSvgItemWrapper.h"
#include "pluginManager/include/pluginManager.h"
#include <QDebug>
@ -55,14 +56,19 @@ GraphicsFunctionModelItem* PluginItemFactory::createItemFromPlugin(
return nullptr;
}
// 创建包装器
PluginItemWrapper *wrapper = new PluginItemWrapper(pluginItem, parent);
if (!wrapper) {
qWarning() << "PluginItemFactory: Failed to create wrapper";
return nullptr;
bool bSvg = pluginItem->containSvg();
GraphicsFunctionModelItem* wrapper = nullptr;
if(bSvg){ //包含Svg
wrapper = new PluginSvgItemWrapper(pluginItem, parent);
}
else{
// 创建包装器
wrapper = new PluginItemWrapper(pluginItem, parent);
}
if (!wrapper) {
return nullptr;
}
// 设置基本属性
wrapper->setItemType(GIT_PluginItem);
wrapper->setName(pluginItem->displayName());

View File

@ -55,6 +55,7 @@ GraphicsFunctionModelItem* PluginItemWrapper::clone() const
// 获取插件类型
QString pluginType = m_pluginItem->typeId();
int nBaseType = m_pluginItem->baseType();
// 保存当前状态
QVariantMap state = saveState();
@ -114,7 +115,7 @@ void PluginItemWrapper::paint(QPainter *painter,
QRectF selectRect = m_cachedBounds.adjusted(-2, -2, 2, 2);
painter->drawRect(selectRect);
// 绘制控制点
/*// 绘制控制点
const qreal handleSize = 6.0;
QRectF handleRect(-handleSize/2, -handleSize/2, handleSize, handleSize);
@ -140,7 +141,7 @@ void PluginItemWrapper::paint(QPainter *painter,
painter->setBrush(handleBrush);
painter->drawEllipse(handleRect);
painter->restore();
}
}*/
}
painter->restore();
@ -357,7 +358,7 @@ QVariantMap PluginItemWrapper::saveState() const
// 这里可以保存插件的关键属性
QStringList propertyKeys = {"fillColor", "borderColor", "borderWidth", "cornerRadius"};
for (const QString &key : propertyKeys) {
QVariant value = m_pluginItem->property(key);
QVariant value = m_pluginItem->getProperty(key);
if (value.isValid()) {
state[key] = value;
}

View File

@ -0,0 +1,449 @@
// pluginItemWrapper.cpp
#include "graphicsItem/pluginSvgItemWrapper.h"
#include "pluginManager/include/pluginManager.h"
#include "baseProperty.h"
#include "graphicsDataModel/fixedPortsModel.h"
#include <QDebug>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
PluginSvgItemWrapper::PluginSvgItemWrapper(ICanvasItem *pluginItem, QGraphicsItem *parent)
: ElectricFunctionModelSvgItem(pluginItem->bounds().toRect(),parent)
, m_pluginItem(pluginItem)
{
if (!m_pluginItem) {
qWarning() << "PluginItemWrapper: pluginItem is null!";
return;
}
// 设置类型
m_Itemtype = GIT_PluginItem;
// 设置初始名称
setName(m_pluginItem->displayName());
// 连接信号
connectSignals();
// 初始化缓存
updateCache();
// 更新坐标
updateCoordinate();
qDebug() << "PluginItemWrapper created for:" << m_pluginItem->typeId();
}
PluginSvgItemWrapper::~PluginSvgItemWrapper()
{
// 删除插件项
if (m_pluginItem) {
m_pluginItem->deleteLater();
}
}
void PluginSvgItemWrapper::setImage_1(QFileInfo info)
{
QByteArray svgData;
QFile svgFile(info.absoluteFilePath());
if (svgFile.open(QIODevice::ReadOnly)) {
svgData = svgFile.readAll();
svgFile.close();
} else {
qDebug() << "can't open imgfile" << svgFile.errorString();
}
QMap<QString,QByteArray> mapData;
if(!svgData.isEmpty()){
mapData["custom"] = svgData;
updateMapSvg(mapData,"custom");
loadSvg(svgData);
updateItem();
}
QString sMeta;
QString sModel;
int nType = -1;
if(_property){
sMeta = _property->metaModelName();
sModel = _property->modelName();
nType = _property->type();
}
if(_pHandle && !sMeta.isEmpty() && !sModel.isEmpty())
_pHandle->updateItemIcon(sMeta,sModel,mapData,"custom",nType,0);
ElectricFunctionModelSvgItem::setImage_1(info);
}
ElectricFunctionModelSvgItem* PluginSvgItemWrapper::clone() const
{
if (!m_pluginItem) {
return nullptr;
}
// 获取场景中的PluginManager
PluginManager *manager = PluginManager::instance();
if (!manager) {
qWarning() << "PluginManager not available for cloning";
return nullptr;
}
// 获取插件类型
QString pluginType = m_pluginItem->typeId();
int nBaseType = m_pluginItem->baseType();
// 保存当前状态
QVariantMap state = saveState();
// 创建新的插件项
ICanvasItem *newPluginItem = manager->createItem(pluginType);
if (!newPluginItem) {
qWarning() << "Failed to create plugin item for cloning:" << pluginType;
return nullptr;
}
// 恢复状态
if (!loadStateIntoPluginItem(newPluginItem, state)) {
qWarning() << "Failed to restore state for cloned item";
delete newPluginItem;
return nullptr;
}
// 创建新的包装器
PluginSvgItemWrapper *clone = new PluginSvgItemWrapper(newPluginItem, parentItem());
// 复制变换属性
clone->setPos(pos());
clone->setRotation(rotation());
clone->setScale(scale());
clone->setZValue(zValue());
// 复制其他属性
clone->copyPropertiesFrom(this);
qDebug() << "Cloned plugin item:" << pluginType;
return clone;
}
void PluginSvgItemWrapper::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
if (!painter || !m_pluginItem) {
return;
}
painter->save();
// 让插件绘制
m_pluginItem->draw(painter, m_cachedBounds);
ElectricFunctionModelSvgItem::paint(painter,option,widget); //调用默认绘制
painter->restore();
}
QRectF PluginSvgItemWrapper::boundingRect() const
{
qreal margin = 4.0; // 为控制点留出空间
return m_cachedBounds.adjusted(-margin, -margin, margin, margin);
}
QPainterPath PluginSvgItemWrapper::shape() const
{
QPainterPath path;
if (!m_pluginItem) {
return path;
}
// 创建简单的矩形路径
// 插件可以提供更精确的形状,这里简化处理
path.addRect(m_cachedBounds);
return path;
}
void PluginSvgItemWrapper::updateCoordinate()
{
if (!m_pluginItem) {
return;
}
// 更新基类属性
QRectF bounds = m_pluginItem->bounds();
m_dWidth = bounds.width();
m_dHeight = bounds.height();
// 更新包围框
m_boundingRect = bounds;
// 更新变换
setTransformOriginPoint(bounds.center());
// 调用基类更新
GraphicsFunctionModelItem::updateCoordinate();
// 更新句柄位置
updateHandles();
}
void PluginSvgItemWrapper::resize(int handle, double dx, double dy, const QPointF &pos)
{
if (!m_pluginItem) {
return;
}
QRectF bounds = m_pluginItem->bounds();
QRectF newBounds = bounds;
// 根据控制点调整大小
switch (handle) {
case H_leftTop:
newBounds.setTopLeft(newBounds.topLeft() + QPointF(dx, dy));
break;
case H_top:
newBounds.setTop(newBounds.top() + dy);
break;
case H_rightTop:
newBounds.setTopRight(newBounds.topRight() + QPointF(dx, dy));
break;
case H_right:
newBounds.setRight(newBounds.right() + dx);
break;
case H_rightBottom:
newBounds.setBottomRight(newBounds.bottomRight() + QPointF(dx, dy));
break;
case H_bottom:
newBounds.setBottom(newBounds.bottom() + dy);
break;
case H_leftBottom:
newBounds.setBottomLeft(newBounds.bottomLeft() + QPointF(dx, dy));
break;
case H_left:
newBounds.setLeft(newBounds.left() + dx);
break;
default:
// 不是控制点,直接移动
move(QPointF(dx, dy));
return;
}
// 确保大小有效
if (newBounds.width() < 10) {
newBounds.setWidth(10);
}
if (newBounds.height() < 10) {
newBounds.setHeight(10);
}
if (newBounds.isValid() && newBounds != bounds) {
m_pluginItem->setBounds(newBounds);
}
}
void PluginSvgItemWrapper::move(const QPointF &delta)
{
if (!m_pluginItem || delta.isNull()) {
return;
}
QRectF bounds = m_pluginItem->bounds();
bounds.translate(delta);
m_pluginItem->setBounds(bounds);
}
ICanvasItem* PluginSvgItemWrapper::pluginItem() const
{
return m_pluginItem;
}
QVariant PluginSvgItemWrapper::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (!m_pluginItem) {
return GraphicsFunctionModelItem::itemChange(change, value);
}
switch (change) {
case ItemSelectedChange:
// 选中状态变化
if (value.toBool()) {
// 选中时的处理
setHandleVisible(true);
} else {
// 取消选中的处理
setHandleVisible(false);
}
break;
case ItemPositionChange: {
// 位置变化
QPointF newPos = value.toPointF();
QPointF delta = newPos - pos();
// 更新插件项的位置
QRectF bounds = m_pluginItem->bounds();
bounds.translate(delta);
m_pluginItem->setBounds(bounds);
return newPos;
}
case ItemRotationChange:
// 旋转变化
// 插件项可能需要处理旋转
break;
case ItemScaleChange:
// 缩放变化
// 插件项可能需要处理缩放
break;
case ItemZValueChange:
// Z值变化
break;
default:
break;
}
return GraphicsFunctionModelItem::itemChange(change, value);
}
void PluginSvgItemWrapper::updateCache()
{
if (m_pluginItem) {
m_cachedBounds = m_pluginItem->bounds();
}
}
void PluginSvgItemWrapper::connectSignals()
{
if (!m_pluginItem) {
return;
}
// 使用旧式语法连接
connect(m_pluginItem, SIGNAL(boundsChanged(QRectF)),
this, SLOT(onPluginBoundsChanged(QRectF)));
connect(m_pluginItem, SIGNAL(propertyChanged(QString, QVariant)),
this, SLOT(onPluginPropertyChanged(QString, QVariant)));
}
QVariantMap PluginSvgItemWrapper::saveState() const
{
QVariantMap state;
if (!m_pluginItem) {
return state;
}
// 保存基本属性
state["type"] = m_pluginItem->typeId();
state["displayName"] = m_pluginItem->displayName();
// 保存几何信息
QRectF bounds = m_pluginItem->bounds();
state["x"] = bounds.x();
state["y"] = bounds.y();
state["width"] = bounds.width();
state["height"] = bounds.height();
// 保存插件特定属性
// 这里可以保存插件的关键属性
QStringList propertyKeys = {"fillColor", "borderColor", "borderWidth", "cornerRadius"};
for (const QString &key : propertyKeys) {
QVariant value = m_pluginItem->getProperty(key);
if (value.isValid()) {
state[key] = value;
}
}
return state;
}
bool PluginSvgItemWrapper::loadStateIntoPluginItem(ICanvasItem *pluginItem, const QVariantMap &state) const
{
if (!pluginItem) {
return false;
}
// 设置几何信息
if (state.contains("x") && state.contains("y") &&
state.contains("width") && state.contains("height")) {
QRectF bounds(
state["x"].toReal(),
state["y"].toReal(),
state["width"].toReal(),
state["height"].toReal()
);
if (bounds.isValid()) {
pluginItem->setBounds(bounds);
}
}
// 设置插件属性
QStringList propertyKeys = {"fillColor", "borderColor", "borderWidth", "cornerRadius"};
for (const QString &key : propertyKeys) {
if (state.contains(key)) {
pluginItem->setProperty(key, state[key]);
}
}
return true;
}
void PluginSvgItemWrapper::copyPropertiesFrom(const PluginSvgItemWrapper *source)
{
if (!source) {
return;
}
// 复制基类属性
m_type = source->m_type;
m_pen = source->m_pen;
m_brush = source->m_brush;
m_dWidth = source->m_dWidth;
m_dHeight = source->m_dHeight;
m_boundingRect = source->m_boundingRect;
m_Itemtype = source->m_Itemtype;
// 复制可见性和使能状态
setVisible(source->isVisible());
setEnabled(source->isEnabled());
// 复制工具提示
setToolTip(source->toolTip());
// 复制自定义数据
setData(0, source->data(0));
// 生成新的ID
setItemId(QUuid::createUuid());
}
void PluginSvgItemWrapper::onPluginBoundsChanged(const QRectF &newBounds)
{
m_cachedBounds = newBounds;
// 更新坐标
updateCoordinate();
// 通知变化
emit itemChanged();
}
void PluginSvgItemWrapper::onPluginPropertyChanged(const QString &key, const QVariant &value)
{
Q_UNUSED(key);
Q_UNUSED(value);
// 属性变化,需要重绘
update();
// 通知变化
emit itemChanged();
}

View File

@ -590,12 +590,15 @@ void BaseSelector::dropEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*,
else
nGraphicType = -1;
if(nGraphicType == 0 || nGraphicType == -1){ //图形类
if(nGraphicType == 0){ //图形类
_model->addGraphicItem(QUuid::createUuid(),"",event->scenePos(),nGraphicType);
}
else{
else if(nGraphicType == 1){ //文字
_model->addGraphicItem(QUuid::createUuid(),"",event->scenePos(),nGraphicType,"文本对象");
}
else{
}
event->acceptProposedAction();
}

View File

@ -72,6 +72,7 @@ private:
MonitorPagesDlg* m_pMonitorPagesDlg;
QDockWidget* m_pMonitorItemsDock;
QDockWidget* m_pMonitorPagesDock;
QDockWidget* m_pPropertyEditorDock;
QDetailsView* m_pPropertiesEditorView;
QAction* _pActMonitor;
};

View File

@ -3,18 +3,15 @@ project(pluginManager)
set(PLUGINMANAGER_HEADER_FILES
include/pluginManager.h
include/genericPluginAdapter.h
../common/include/compiler.hpp
../common/include/export.hpp
../common/include/operatingSystem.hpp
../common/include/pluginCommon/iPluginAdapter.h
../common/include/pluginCommon/iCanvasItem.h
)
set(PLUGINMANAGER_SOURCE_FILES
source/pluginManager.cpp
source/genericPluginAdapter.cpp
)

View File

@ -1,60 +0,0 @@
// genericPluginAdapter.h
#pragma once
#include "pluginCommon/iPluginAdapter.h"
#include <QObject>
class ICanvasItem;
// 通用适配器实现
class GenericPluginAdapter :public IPluginAdapter
{
Q_OBJECT
public:
explicit GenericPluginAdapter(ICanvasItem *pluginItem, QObject *parent = nullptr);
virtual ~GenericPluginAdapter();
// IPluginAdapter接口
QString adapterType() const override { return "generic"; }
QString pluginType() const override;
QRectF bounds() const override;
void setBounds(const QRectF &bounds) override;
void paint(QPainter *painter, const QRectF &bounds) override;
QPainterPath shape() const override;
QVariant property(const QString &key) const override;
void setProperty(const QString &key, const QVariant &value) override;
void move(const QPointF &delta) override;
void resize(const QRectF &newBounds) override;
bool isSelected() const override;
void setSelected(bool selected) override;
QVariantMap saveState() const override;
bool loadState(const QVariantMap &state) override;
// 获取原始插件项
ICanvasItem* pluginItem() const;
signals:
void boundsChanged(const QRectF &newBounds);
void propertyChanged(const QString &key, const QVariant &value);
void selectionChanged(bool selected);
void adapterChanged();
private:
ICanvasItem *m_pluginItem = nullptr;
bool m_selected = false;
QRectF m_cachedBounds;
void updateCache();
void connectSignals();
private slots:
void onPluginBoundsChanged(const QRectF &newBounds);
void onPluginPropertyChanged(const QString &key, const QVariant &value);
};

View File

@ -61,7 +61,7 @@ QPainterPath GenericPluginAdapter::shape() const
QVariant GenericPluginAdapter::property(const QString &key) const
{
return m_pluginItem ? m_pluginItem->property(key) : QVariant();
return m_pluginItem ? m_pluginItem->getProperty(key) : QVariant();
}
void GenericPluginAdapter::setProperty(const QString &key, const QVariant &value)

View File

@ -248,7 +248,7 @@ void PluginManager::registerBuiltinShape(const QString &shapeId,
ShapeDescriptor desc;
desc.id = shapeId;
desc.name = name;
desc.category = "内置形状";
desc.category = -1;
desc.iconPath = iconPath;
d->builtinDescriptors[shapeId] = desc;

View File

@ -43,6 +43,7 @@ CMainWindow::CMainWindow(QWidget *parent)
m_pMonitorPagesDock = nullptr;
m_pPropertiesEditorView = nullptr;
_pActMonitor = nullptr;
m_pPropertyEditorDock = nullptr;
qRegisterMetaType<PropertyStateInfo>("PropertyStateInfo");
initializeDockUi();
@ -136,12 +137,13 @@ void CMainWindow::initializeDockUi()
connect(&ProjectModelManager::instance(),&ProjectModelManager::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
m_pPropertiesEditorView = new QDetailsView();
BaseDockWidget* PropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
PropertyEditorDock->setWidget(m_pPropertiesEditorView);
PropertyEditorDock->setMinimumSize(350,150);
m_pPropertiesEditorView->setObject(m_pDiagramCavas);
PropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea,PropertyEditorDock);
m_pPropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
m_pPropertyEditorDock->setWidget(m_pPropertiesEditorView);
m_pPropertyEditorDock->setMinimumSize(350,150);
m_pPropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea,m_pPropertyEditorDock);
m_pPropertiesEditorView->setObject(new QObject(this));
m_pPropertyEditorDock->hide();
connect(m_pDiagramCavas,&DiagramCavas::selectTarget,this,&CMainWindow::onCavasItemSelected);
}
@ -309,8 +311,9 @@ void CMainWindow::onSignal_deleteItem()
void CMainWindow::onCavasItemSelected(QObject* obj)
{
if(m_pPropertiesEditorView)
m_pPropertiesEditorView->setObject(obj);
m_pPropertyEditorDock->show();
m_pPropertiesEditorView->setObject(obj);
}
GraphicElementsPanel* CMainWindow::graphicsElementsPanel() const