add HMI dynamic property setting

This commit is contained in:
baiYue 2026-04-08 14:17:47 +08:00
parent 789ba990d4
commit 4203022e3a
17 changed files with 344 additions and 9 deletions

View File

@ -62,6 +62,7 @@ set(H_HEADER_FILES
include/enhancedToolBar.h
include/configToolBar.h
include/draggableToolButton.h
include/runtimeDialog.h
common/include/tools.h
common/include/httpInterface.h
@ -104,6 +105,7 @@ set(CPP_SOURCE_FILES
source/enhancedToolBar.cpp
source/configToolBar.cpp
source/draggableToolButton.cpp
source/runtimeDialog.cpp
common/source/httpInterface.cpp
common/source/tools.cpp

View File

@ -49,8 +49,10 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/bayMeasureDlg.h
include/basePropertyProxy.h
include/basePannelPropertyProxy.h
include/baseItemPropertyProxy.h
include/dataSourceDlg.h
include/createHMIdlg.h
include/propertyDialog.h
include/graphicsDataModel/baseModel.h
include/graphicsDataModel/fixedPortsModel.h
include/graphicsItem/graphicsItemGroup.h
@ -179,8 +181,10 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/bayMeasureDlg.cpp
source/basePropertyProxy.cpp
source/basePannelPropertyProxy.cpp
source/baseItemPropertyProxy.cpp
source/dataSourceDlg.cpp
source/createHMIdlg.cpp
source/propertyDialog.cpp
source/graphicsDataModel/baseModel.cpp
source/graphicsDataModel/fixedPortsModel.cpp
source/graphicsItem/graphicsItemGroup.cpp

View File

@ -0,0 +1,29 @@
#ifndef BASEITEMPROPERTYPROXY_H
#define BASEITEMPROPERTYPROXY_H
/****************************
* item属性代理基类
* *************************/
#include <QUuid>
#include "basePropertyProxy.h"
class GraphicsFunctionModelItem;
class FixedPortsModel;
class BaseItemPropertyProxy : public BasePropertyProxy {
Q_OBJECT
public:
Q_PROPERTY(QString Name READ getName WRITE setName)
Q_PROPERTY(QMap<QString,double> Property READ getMap WRITE setMap)
public:
BaseItemPropertyProxy(GraphicsFunctionModelItem*);
~BaseItemPropertyProxy();
public:
virtual QString getName() const;
virtual void setName(QString);
virtual QMap<QString,double> getMap();
virtual void setMap(QMap<QString,double>);
protected:
GraphicsFunctionModelItem* _pItem;
FixedPortsModel* _pControl;
};
#endif //BASEITEMPROPERTYPROXY_H

View File

@ -30,6 +30,8 @@ class DataSourceDlg;
class CreateHMIdlg;
class PluginManager;
class PluginItemFactory;
class QDetailsView;
class PropertyDlg;
class DIAGRAM_DESIGNER_PUBLIC DiagramCavas : public QMdiArea
{
@ -49,6 +51,10 @@ public:
QMap<QString,PluginTypeInfo> getPluginShapeInfo() {return m_pluginInfo;}
public:
void initial();
void setCurMode(int nMode);
int getCurMode(){return _curMode;}
void showPropertyDlg(); //加载运行时属性栏
void hidePropertyDlg();
signals:
void prepareUpdateItems(QList<HierarchyItem>,bool refresh);
void prepareSelectItems(QList<HierarchyItem>);
@ -122,6 +128,8 @@ private:
bool loadPluginConfig(const QString&); //载入插件配置文件
bool parsePluginConfig(const QJsonObject& root); //解析插件配置文件
void addShortcuts(); //快捷键
private:
QMap<QString,QPair<MonitorPanel*,QMdiSubWindow*>> m_mapMonitorPanel; //监控时panel
int _pageIndex;
@ -133,10 +141,13 @@ private:
StructDataPreviewDlg* _structDataPreviewDlg;
ExtraPropertyManager* _extraPropertyManager;
CreateHMIdlg* _createHMIDlg;
QDetailsView* _pPropertyPage; //属性页
PropertyDlg* _pPropertyDlg; //存放属性页dlg
PluginManager* m_pluginManager; //插件管理类
PluginItemFactory* m_itemFactory; //插件图元工厂类
QMap<QString,PluginTypeInfo> m_pluginInfo; //插件对照信息
int _curMode = 0; //当前运行模式 0编辑1运行
};
#endif

View File

@ -3,6 +3,8 @@
#include "graphicsItem/graphicsBaseItem.h"
class BaseItemPropertyProxy;
class GraphicsFunctionModelItem : public GraphicsProjectModelItem //功能模item
{
Q_OBJECT
@ -12,10 +14,15 @@ public:
GraphicsFunctionModelItem(QGraphicsItem *parent);
virtual ~GraphicsFunctionModelItem();
QMap<QString,bool> getMap();
QMap<QString,bool> getMap(); //bool值为数据源指针类型
void setMap(QMap<QString,bool>);
void setPropertyProxy(BaseItemPropertyProxy* p) {_pPropertyProxy = p;}
BaseItemPropertyProxy* getPropertyProxy() {return _pPropertyProxy;}
protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
protected:
BaseItemPropertyProxy* _pPropertyProxy; //属性页代理
};

View File

@ -239,6 +239,7 @@ public:
virtual void setDynamicLayoutRadius(qreal radius);
virtual QMap<QString,HandleText*> getDynamicText() {return m_mapDynamicText;}
void setHandle(FixedPortsModel* p){_pHandle = p;}
FixedPortsModel* getHandle() {return _pHandle;}
virtual void img_1_selected(QString sMeta,QString sModel,QByteArray img){};
virtual void img_2_selected(QString sMeta,QString sModel,QByteArray img){};
virtual void img_3_selected(QString sMeta,QString sModel,QByteArray img){};

View File

@ -0,0 +1,21 @@
#ifndef PROPERTYDLG_H
#define PROPERTYDLG_H
/*********存放属性栏的窗口(运行时)*******/
#include <QDialog>
#include <QVBoxLayout>
class PropertyDlg : public QDialog
{
Q_OBJECT
public:
PropertyDlg(QWidget *parent = nullptr);
~PropertyDlg();
void setContent(QWidget* content);
void removeContent(QWidget* content);
private:
QVBoxLayout* _layout;
};
#endif

View File

@ -0,0 +1,51 @@
#include "baseItemPropertyProxy.h"
#include "graphicsItem/functionModelItem/graphicsFunctionModelItem.h"
#include "graphicsDataModel/fixedPortsModel.h"
#include "baseProperty.h"
BaseItemPropertyProxy::BaseItemPropertyProxy(GraphicsFunctionModelItem* pItem)
: BasePropertyProxy(pItem)
,_pItem(pItem)
,_pControl(nullptr)
{
_pControl= _pItem->getHandle();
}
BaseItemPropertyProxy::~BaseItemPropertyProxy()
{
}
QString BaseItemPropertyProxy::getName() const
{
return _pItem->getName();
}
void BaseItemPropertyProxy::setName(QString str)
{
}
QMap<QString,double> BaseItemPropertyProxy::getMap()
{
QUuid uid = _pItem->getProperty()->uuid();
QMap<QString,double> map;
if(_pControl){
auto pPara = _pControl->getMonitorPara();
auto lstInfo = pPara.value(uid);
if(!lstInfo.isEmpty()){
for(auto &info:lstInfo){
if(info.bSelected)
map[info.sName] = info.mapValue.size()?info.mapValue.last():0; //取最新的值
}
}
}
return map;
}
void BaseItemPropertyProxy::setMap(QMap<QString,double>)
{
//todo:接口修改参量
}

View File

@ -5,6 +5,7 @@
#include <QLibrary>
#include <QMetaMethod>
#include <QApplication>
#include <QShortcut>
#include "monitorPanel.h"
#include "diagramCavas.h"
#include "dataBase.h"
@ -32,6 +33,8 @@
#include "propertyType/dataSourceType.h"
#include "basePannelPropertyProxy.h"
#include "QDetailsView.h"
#include "propertyDialog.h"
DiagramCavas::DiagramCavas(QWidget *parent)
: QMdiArea(parent)
@ -44,6 +47,8 @@ DiagramCavas::DiagramCavas(QWidget *parent)
,_createHMIDlg(nullptr)
,m_pluginManager(nullptr)
,m_itemFactory(nullptr)
,_pPropertyPage(nullptr)
,_pPropertyDlg(nullptr)
{
_pageIndex = 0;
}
@ -168,6 +173,54 @@ void DiagramCavas::initial()
QString pluginsDir = QApplication::applicationDirPath() + "/plugins";
m_pluginManager->addPluginDirectory(pluginsDir);
m_pluginManager->loadAllPlugins(pluginsDir);
_pPropertyDlg = new PropertyDlg(parentWidget());
_pPropertyDlg->hide();
addShortcuts();
//setViewMode(QMdiArea::TabbedView);
}
void DiagramCavas::setCurMode(int nMode)
{
_curMode = nMode;
if(_curMode == 1){ //运行模式下
showPropertyDlg();
//setViewMode(QMdiArea::SubWindowView);
}
else{
hidePropertyDlg();
//setViewMode(QMdiArea::TabbedView);
}
}
void DiagramCavas::showPropertyDlg()
{
if(_pPropertyPage == nullptr){ //未被初始化
_pPropertyPage = new QDetailsView();
_pPropertyPage->setObject(new QObject(this));
}
_pPropertyDlg->setContent(_pPropertyPage);
_pPropertyDlg->show();
QScreen *screen = QGuiApplication::screenAt(parentWidget()->geometry().center());
if (!screen) {
screen = QGuiApplication::primaryScreen();
}
QRect screenGeometry = screen->geometry();
QRect dialogRect = _pPropertyDlg->geometry();
// 计算位置:水平靠右,垂直居中
int x = screenGeometry.right() - dialogRect.width() - 10; // 留10像素边距
int y = screenGeometry.center().y() - dialogRect.height() / 2;
_pPropertyDlg->move(x, y);
}
void DiagramCavas::hidePropertyDlg()
{
_pPropertyDlg->removeContent(_pPropertyPage);
_pPropertyDlg->hide();
}
void DiagramCavas::onSignal_addDrawingPanel(PowerEntity* pItem,DiagramMode mode,QString parent)
@ -536,6 +589,20 @@ bool DiagramCavas::parsePluginConfig(const QJsonObject& root)
return true;
}
void DiagramCavas::addShortcuts()
{
QShortcut* toggleProp = new QShortcut(QKeySequence("Ctrl+P"), this);
connect(toggleProp, &QShortcut::activated, [this]() {
if(_pPropertyDlg->isVisible()){
hidePropertyDlg();
}
else{
if(_curMode == 1)
showPropertyDlg();
}
});
}
void DiagramCavas::resizeEvent(QResizeEvent* event)
{
if(_cornerButton)
@ -544,8 +611,13 @@ void DiagramCavas::resizeEvent(QResizeEvent* event)
void DiagramCavas::onTargetSelected(QObject* obj)
{
if(obj)
emit selectTarget(obj);
if(obj){
if(_curMode == 0)
emit selectTarget(obj);
else
_pPropertyPage->setObject(obj);
}
}
/****************************************************/

View File

@ -51,6 +51,7 @@
#include "graphicsItem/handleText.h"
#include "bayMeasureDlg.h"
#include "basePannelPropertyProxy.h"
#include "baseItemPropertyProxy.h"
#include "common/core_model/types.h"
#include "graphicsItem/pluginSvgItemWrapper.h"
@ -775,6 +776,8 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
item->bindProperty(pro); //绑定模型
item->updateByProperty(); //使用模型更新自身
item->setHandle(this);
auto pProxy = new BaseItemPropertyProxy(item); //设置运行时属性代理
item->setPropertyProxy(pProxy);
_nodeItem.insert(id,item);
//connect(item,&GraphicsFunctionModelItem::ifExist,this,&FixedPortsModel::onSignal_ifExits);
connect(item,&GraphicsBaseItem::itemRotated,this,[this](GraphicsBaseItem* pBase){
@ -951,6 +954,7 @@ QString FixedPortsModel::addConnectLline(QUuid lineId,QUuid srcId,QUuid destId,Q
ElectricFunctionModelConnectLineItem* pItem = new ElectricFunctionModelConnectLineItem();
pItem->setItemId(lineId);
pItem->setItemType(GIT_link);
pItem->setHandle(this);
_scene->addItem(pItem);
ItemPort* ptSrc = src->getPortById(srcPort.toString());
@ -973,6 +977,8 @@ QString FixedPortsModel::addConnectLline(QUuid lineId,QUuid srcId,QUuid destId,Q
pPro->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos));
ptDest->setConnect(pItem);
auto pProxy = new BaseItemPropertyProxy(pItem); //设置运行时属性代理
pItem->setPropertyProxy(pProxy);
addNodeItem(pItem->itemId(),pItem);
pItem->bindProperty(pPro);
}
@ -1725,7 +1731,9 @@ void FixedPortsModel::onDataTimerOut()
void FixedPortsModel::onSelectionChanged()
{
QList<QGraphicsItem*> selectedItems = _scene->selectedItems();
if(_cavas){
if(_cavas){
int nMode = _cavas->getCurMode();
if(nMode == 0){
if(selectedItems.count() != 1) {
if(_widget)
_cavas->onTargetSelected(_widget->getPropertyProxy());
@ -1733,6 +1741,16 @@ void FixedPortsModel::onSelectionChanged()
}
GraphicsBaseItem *item = static_cast<GraphicsBaseItem*>(selectedItems.first());
_cavas->onTargetSelected(item);
}
else if(nMode == 1){
if(selectedItems.count() != 1) {
return;
}
GraphicsFunctionModelItem *item = static_cast<GraphicsFunctionModelItem*>(selectedItems.first());
if(item){
_cavas->onTargetSelected(item->getPropertyProxy());
}
}
}
}

View File

@ -1,9 +1,11 @@
#include "graphicsItem/functionModelItem/graphicsFunctionModelItem.h"
#include "baseProperty.h"
#include "graphicsDataModel/fixedPortsModel.h"
#include "baseItemPropertyProxy.h"
GraphicsFunctionModelItem::GraphicsFunctionModelItem(QGraphicsItem *parent)
: GraphicsProjectModelItem(parent)
,_pPropertyProxy(nullptr)
{
}

View File

@ -0,0 +1,31 @@
#include "propertyDialog.h"
#include <QVBoxLayout>
#include <QKeyEvent>
PropertyDlg::PropertyDlg(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("属性显示");
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint );
_layout = new QVBoxLayout(this);
_layout->setContentsMargins(0, 0, 0, 0);
setMinimumSize(300, 500);
}
PropertyDlg::~PropertyDlg()
{
}
void PropertyDlg::setContent(QWidget* content)
{
if(content)
_layout->addWidget(content);
}
void PropertyDlg::removeContent(QWidget* content)
{
if(content)
_layout->removeWidget(content);
}

View File

@ -22,6 +22,7 @@ class DiagramView;
class MonitorItemsDlg;
class MonitorPagesDlg;
class QDetailsView;
class RuntimeDialog;
class CMainWindow : public QMainWindow
{
@ -38,7 +39,7 @@ protected:
private:
void initializeDockUi();
void initializeAction();
void refreshLayout();
private slots:
void onAction_zoomIn();
void onAction_zoomOut();
@ -53,7 +54,7 @@ private slots:
void onCavasItemSelected(QObject*);
public:
GraphicElementsPanel* graphicsElementsPanel() const;
void setMode(int nMode = 0); //切换模式
private:
QAction* SavePerspectiveAction = nullptr;
QWidgetAction* PerspectiveListAction = nullptr;
@ -75,5 +76,7 @@ private:
QDockWidget* m_pPropertyEditorDock;
QDetailsView* m_pPropertiesEditorView;
QAction* _pActMonitor;
int _nMode = 0; //0编辑1运行
RuntimeDialog* m_pRuntimeDlg;
};
#endif // MAINWINDOW_H

22
include/runtimeDialog.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef RUNTIMEDIALOG_H
#define RUNTIMEDIALOG_H
#include <QDialog>
#include <QVBoxLayout>
// 运行时对话框
class RuntimeDialog : public QDialog {
Q_OBJECT
public:
RuntimeDialog(QWidget* parent = nullptr);
void setContent(QWidget* content);
signals:
void exitRuntime();
protected:
void keyPressEvent(QKeyEvent* event) override;
private:
QVBoxLayout* _layout;
};
#endif //RUNTIMEDIALOG_H

View File

@ -45,9 +45,9 @@ void EnhancedToolBar::addTool(const QString &toolType, const QString &toolName,
m_buttons[toolType] = button;
// 如果没有当前工具,设置第一个为当前
if (m_currentTool.isEmpty()) {
/*if (m_currentTool.isEmpty()) {
setCurrentTool(toolType);
}
}*/
}
void EnhancedToolBar::onToolButtonClicked()

View File

@ -26,6 +26,7 @@
#include "QDetailsView.h"
#include "baseDockWidget.h"
#include "configToolBar.h"
#include "runtimeDialog.h"
#include "QDetailsView.h"
@ -44,6 +45,7 @@ CMainWindow::CMainWindow(QWidget *parent)
m_pPropertiesEditorView = nullptr;
_pActMonitor = nullptr;
m_pPropertyEditorDock = nullptr;
m_pRuntimeDlg = nullptr;
qRegisterMetaType<PropertyStateInfo>("PropertyStateInfo");
initializeDockUi();
@ -134,6 +136,12 @@ void CMainWindow::initializeDockUi()
this->setCentralWidget(m_pDiagramCavas);
connect(m_pElectricElementsBox,&ElectricElementsBox::addEletricItem,m_pDiagramCavas,&DiagramCavas::onSignal_addGraphicsItem);
m_pRuntimeDlg = new RuntimeDialog(this);
m_pRuntimeDlg->hide();
connect(m_pRuntimeDlg,&RuntimeDialog::exitRuntime,this,[&](){
setMode(0);
});
connect(&ProjectModelManager::instance(),&ProjectModelManager::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
m_pPropertiesEditorView = new QDetailsView();
@ -202,7 +210,11 @@ void CMainWindow::initializeAction()
QAction* actNewEditor = ui->menuFile->addAction(QString::fromWCharArray(L"新建组态"));
QAction* actRun = ui->menuMode->addAction(QString::fromWCharArray(L"运行"));
connect(actRun,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_runPage);
actRun->setShortcut(QKeySequence(Qt::Key_F5));
//connect(actRun,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_runPage);
connect(actRun,&QAction::triggered,this,[&](){
setMode(1);
});
QAction* actEditBay = ui->menuProject->addAction(QString::fromWCharArray(L"管理间隔"));
connect(actEditBay,&QAction::triggered,this,&CMainWindow::onAction_editBay);
@ -235,6 +247,20 @@ void CMainWindow::initializeAction()
}
void CMainWindow::refreshLayout()
{
if(_nMode == 0){ //编辑模式
m_pRuntimeDlg->hide();
this->show();
this->setCentralWidget(m_pDiagramCavas);
}
else{
this->hide();
m_pRuntimeDlg->setContent(m_pDiagramCavas);
m_pRuntimeDlg->showMaximized();
}
}
void CMainWindow::onAction_zoomIn()
{
//m_pDrawingPanel->grahpicsViewZoomIn();
@ -327,4 +353,16 @@ GraphicElementsPanel* CMainWindow::graphicsElementsPanel() const
}
}
void CMainWindow::setMode(int nMode)
{
if(_nMode != nMode){
_nMode = nMode;
m_pPropertyEditorDock->setWidget(nullptr);
m_pDiagramCavas->setCurMode(nMode);
}
if(_nMode == 0){
m_pPropertyEditorDock->setWidget(m_pPropertiesEditorView); //属性页设置回主界面
}
refreshLayout();
}

23
source/runtimeDialog.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "runtimeDialog.h"
#include <QVBoxLayout>
#include <QKeyEvent>
RuntimeDialog::RuntimeDialog(QWidget *parent)
: QDialog(parent,Qt::FramelessWindowHint)
{
_layout = new QVBoxLayout(this);
_layout->setContentsMargins(0, 0, 0, 0);
}
void RuntimeDialog::keyPressEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Escape) {
emit exitRuntime();
hide();
}
}
void RuntimeDialog::setContent(QWidget* content)
{
if(content)
_layout->addWidget(content);
}