123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- #include "WindowAppPouFrame.h"
- #include "WindowAppPouScene.h"
- #include "DialogNewVariable.h"
- #include "GvlManager.h"
- #include "PouManager.h"
- #include "VPCommand.h"
- //template<typename T>
- //void SetValue(VALUE& value, T& t)
- //{
- // value.Ptr = (void**)&t;
- //
- // qDebug() << "ForTest valueIn: " << *(int*)value.Ptr;
- // // For Test
- // *(int*)value.Ptr = 40;
- // // 此时valueIn的值变为40
- // qDebug() << "ForTest valueIn: " << *(int*)value.Ptr;
- //}
- WindowAppPouFrame::WindowAppPouFrame(const QString& strTitle, QWidget* parent)
- : QWidget(parent)
- , m_strTitle(strTitle)
- , actionUndo(nullptr)
- , actionRedo(nullptr)
- {
- ui.setupUi(this);
- // 2022-3-2增加,创建变量表格的同时就顺便创建对应的局部变量组(空)
- g_pGvlManager->addNewGroup(m_strTitle, TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE, GVL_MODE::GVL_BASIC);
- // 初始化图像子界面工具栏
- this->initPouToolbar();
- // 初始化局部变量子界面工具栏
- this->initGvlToolbar();
- // 初始化变量表格
- ui.tableVariable->initTable(m_strTitle, GVL_MODE::GVL_BASIC);
- ui.graphicsView->initView(m_strTitle, this);
- // 初始化UI
- this->initUI();
- // 避免在硬件组态中创建局部变量表和调试页面
- if (m_strTitle == GROUP_NAME_HARDWARE)
- {
- // 隐藏调试页面
- ui.pouDebugView->hide();
- // 既可以删除Tab
- ui.tabWidget->removeTab(0);
- // 也可以隐藏Tab
- //ui.tabWidget->setTabEnabled(0, false);
- //ui.tabWidget->setStyleSheet("QTabBar::tab:disabled {width: 0; color: transparent;}");
-
- // 隐藏工具条
- ui.toolbarPouFrame->hide();
- }
- // 生成鸟瞰图
- m_pNavView = new WindowAppPouNavView(this);
- m_pNavView->setFixedSize(220, 165);
- // 将当前Scene绑定到鸟瞰图中进行同步
- m_pNavView->setScene((QGraphicsScene*)ui.graphicsView->getScene());
- // 将View也绑定到鸟瞰图中同步
- m_pNavView->setMainView(ui.graphicsView);
- // 调整VIew
- m_pNavView->fitInView(m_pNavView->sceneRect(), Qt::KeepAspectRatio);
- // 设置透明度
- m_pNavView->setOpacity(0, false);
- // 绑定鸟瞰图缩放时的同步刷新动作
- connect(ui.graphicsView, &WindowAppPouView::navigatorViewRequired, this, [=](bool required, const QTransform& tf)
- {
- Q_UNUSED(required);
- Q_UNUSED(tf);
- //m_pNavView->setTransform(WindowAppPouView::resetScale(tf));
- m_pNavView->fitInView(m_pNavView->sceneRect(), Qt::KeepAspectRatio);
- m_pNavView->setVisible(required);
- m_pNavView->updateMainViewportRegion();
- }
- );
- // 矩形区域变动时的响应动作
- connect(ui.graphicsView, &WindowAppPouView::viewportRectChanged, m_pNavView, &WindowAppPouNavView::updateMainViewportRegion);
- // 调整分割线
- connect(ui.splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(slotSplitterMoved(int, int)));
- #ifdef DEBUG_ON_GVL
- VARIABLE* pNewVariable = new VARIABLE(
- m_strTitle,
- true,
- "int_lvl_test1", "int", "-30", "Comment1"
- );
- this->addNewVariable(pNewVariable);
- pNewVariable = new VARIABLE(
- m_strTitle,
- true, "int_lvl_test2", "int", "150", "Comment2"
- );
- this->addNewVariable(pNewVariable);
- pNewVariable = new VARIABLE(
- m_strTitle,
- true, "int_lvl_test3", "int", "300", "This value is 300."
- );
- this->addNewVariable(pNewVariable);
- pNewVariable = new VARIABLE(
- m_strTitle,
- false, "double_lvl_test3", "double", "3.1415926", "This is a double variable"
- );
- this->addNewVariable(pNewVariable);
- #endif
- }
- WindowAppPouFrame::~WindowAppPouFrame()
- {
- }
- /// <summary>
- /// UI元素初始化
- /// </summary>
- void WindowAppPouFrame::initUI()
- {
- ui.splitter->setOpaqueResize(false);
- }
- /// <summary>
- /// 初始化局部变量子界面工具栏
- /// </summary>
- void WindowAppPouFrame::initGvlToolbar()
- {
- m_GvlToolbar = new QToolBar(ui.toolbarVariable);
- m_GvlToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
- m_GvlToolbar->setIconSize(QSize(14, 14));
- QAction* actionNew = new QAction(QIcon(":/image/New.png"), ("New"));
- QAction* actionMoveUp = new QAction(QIcon(":/image/Up.png"), ("Move up"));
- QAction* actionMoveDown = new QAction(QIcon(":/image/Down.png"), ("Move down"));
- QAction* actionDel = new QAction(QIcon(":/image/Del.png"), ("Delete"));
- m_GvlToolbar->addAction(actionNew);
- m_GvlToolbar->addSeparator();
- m_GvlToolbar->addAction(actionMoveUp);
- m_GvlToolbar->addAction(actionMoveDown);
- m_GvlToolbar->addSeparator();
- m_GvlToolbar->addAction(actionDel);
- // 增加工具栏的消息响应
- connect(actionNew, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlNew);
- connect(actionMoveUp, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlMoveUp);
- connect(actionMoveDown, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlMoveDown);
- connect(actionDel, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlDelete);
- // 设置为白色背景色
- // m_LvlToolbar->setStyleSheet("background-color:rgb(255,255,255)");
- }
- /// <summary>
- /// 初始化图形子界面工具栏
- /// </summary>
- void WindowAppPouFrame::initPouToolbar()
- {
- // CAUTION: 这里调试了好久,如果QToolBar的父窗体是QMdiSubWindow的话,这里的工具栏会变成那种弹出式的
- // 只有父窗体是View的时候才会是那种正常工具栏
- m_PouToolbar = new QToolBar(ui.toolbarPouFrame);
- m_PouToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
- actionMoveUp = new QAction(QIcon(":/image/ZorderTop.png"), ("MoveUp"));
- actionMoveDown = new QAction(QIcon(":/image/ZorderBottom.png"), ("MoveDown"));
- actionMoveFirst = new QAction(QIcon(":/image/ZorderUp.png"), ("MoveFirst"));
- actionMoveLast = new QAction(QIcon(":/image/ZorderDown.png"), ("MoveLast"));
- actionAlignLeft = new QAction(QIcon(":/image/AlignLeft.png"), ("Align Left"));
- actionAlignTop = new QAction(QIcon(":/image/AlignTop.png"), ("Align Top"));
- actionAlignRight = new QAction(QIcon(":/image/AlignRight.png"), ("Align Right"));
- actionAlignBottom = new QAction(QIcon(":/image/AlignBottom.png"), ("Align Bottom"));
- // 2022-9-29,增加了Undo和Redo按钮
- actionUndo = new QAction(QIcon(":/image/Undo.png"), ("Undo"));
- actionRedo = new QAction(QIcon(":/image/Redo.png"), ("Redo"));
- actionOption = new QAction(QIcon(":/image/Option.png"), ("Options"));
- actionRunOnce = new QAction(QIcon(":/image/RunOnce.png"), ("Run Once"));
- actionSingleStep = new QAction(QIcon(":/image/RunOnce.png"), ("Single Step"));
- m_PouToolbar->addAction(actionMoveUp);
- m_PouToolbar->addAction(actionMoveDown);
- m_PouToolbar->addAction(actionMoveFirst);
- m_PouToolbar->addAction(actionMoveLast);
- m_PouToolbar->addSeparator();
- m_PouToolbar->addAction(actionAlignLeft);
- m_PouToolbar->addAction(actionAlignTop);
- m_PouToolbar->addAction(actionAlignRight);
- m_PouToolbar->addAction(actionAlignBottom);
- m_PouToolbar->addSeparator();
- // 2022-9-29,增加了Undo和Redo按钮
- m_PouToolbar->addAction(actionUndo);
- m_PouToolbar->addAction(actionRedo);
- m_PouToolbar->addSeparator();
- m_PouToolbar->addAction(actionOption);
- m_PouToolbar->addAction(actionRunOnce);
- m_PouToolbar->addAction(actionSingleStep);
- m_PouToolbar->setIconSize(QSize(14, 14));
- connect(actionMoveUp, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveUp);
- connect(actionMoveDown, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveDown);
- connect(actionMoveFirst, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveFirst);
- connect(actionMoveLast, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveLast);
- connect(actionAlignLeft, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignLeft);
- connect(actionAlignTop, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignTop);
- connect(actionAlignRight, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignRight);
- connect(actionAlignBottom, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignBottom);
- connect(actionUndo, &QAction::triggered, this, &WindowAppPouFrame::onToolUndo);
- connect(actionRedo, &QAction::triggered, this, &WindowAppPouFrame::onToolRedo);
- connect(actionOption, &QAction::triggered, this, &WindowAppPouFrame::onToolOption);
- connect(actionRunOnce, &QAction::triggered, this, &WindowAppPouFrame::onToolRunOnce);
- connect(actionSingleStep, &QAction::triggered, this, &WindowAppPouFrame::onToolSingleStep);
- }
- /// <summary>
- /// Toolbar - New
- /// </summary>
- void WindowAppPouFrame::onToolGvlNew()
- {
- // qDebug() << "WindowAppGvlView::onToolNew";
- // 弹出新增变量对话框
- DialogNewVariable dlgNewVar(GVL_MODE::GVL_BASIC, this);
- dlgNewVar.setWindowModality(Qt::WindowModal);
- dlgNewVar.setGroup(this->m_strTitle);
- dlgNewVar.setTagNumber(ui.tableVariable->rowCount());
- int res = dlgNewVar.exec();
- if (res != QDialog::Accepted)
- {
- return;
- }
- // 根据用户输入构造新的变量
- VARIABLE* pNewVariable = new VARIABLE(
- m_strTitle,
- dlgNewVar.m_bSerialized,
- dlgNewVar.m_strName,
- dlgNewVar.m_strType,
- dlgNewVar.m_strValue,
- dlgNewVar.m_strComment,
- g_pGvlManager->getVariablesCountByGroup(m_strTitle),
- true
- );
- // 在界面和数据结构中添加新的变量
- this->addNewVariable(pNewVariable);
- // 数据结构中添加本变量信息
- g_pGvlManager->addNewVariable(
- m_strTitle,
- pNewVariable
- );
- //// 表格中添加一行
- //ui.tableVariable->addLocalVariable(
- // dlgNewVar.m_bSerialized,
- // dlgNewVar.m_strName,
- // dlgNewVar.m_strType,
- // dlgNewVar.m_strValue,
- // dlgNewVar.m_strComment
- //);
- }
- /// <summary>
- /// Toolbar - Gvl MoveUp
- /// </summary>
- void WindowAppPouFrame::onToolGvlMoveUp()
- {
- ui.tableVariable->onVariableMoveUp();
- }
- /// <summary>
- /// Toolbar - Gvl MoveDown
- /// </summary>
- void WindowAppPouFrame::onToolGvlMoveDown()
- {
- ui.tableVariable->onVariableMoveDown();
- }
- /// <summary>
- /// Toolbar - Gvl Delete
- /// </summary>
- void WindowAppPouFrame::onToolGvlDelete()
- {
- ui.tableVariable->onVariableDelete();
- }
- /// <summary>
- /// 工具序号 减 1
- /// </summary>
- void WindowAppPouFrame::onToolMoveUp()
- {
- ui.graphicsView->getScene()->BlockMoveUp();
- }
- /// <summary>
- /// 工具序号 加 1
- /// </summary>
- void WindowAppPouFrame::onToolMoveDown()
- {
- ui.graphicsView->getScene()->BlockMoveDown();
- }
- /// <summary>
- /// 工具序号 置顶
- /// </summary>
- void WindowAppPouFrame::onToolMoveFirst()
- {
- ui.graphicsView->getScene()->BlockMoveFirst();
- }
- /// <summary>
- /// 工具序号 置底
- /// </summary>
- void WindowAppPouFrame::onToolMoveLast()
- {
- ui.graphicsView->getScene()->BlockMoveLast();
- }
- /// <summary>
- /// 工具左对齐
- /// </summary>
- void WindowAppPouFrame::onToolAlignLeft()
- {
- ui.graphicsView->getScene()->BlockAlignLeft();
- }
- /// <summary>
- /// 功能块顶对齐
- /// </summary>
- void WindowAppPouFrame::onToolAlignTop()
- {
- ui.graphicsView->getScene()->BlockAlignTop();
- }
- /// <summary>
- /// 功能块右对齐
- /// </summary>
- void WindowAppPouFrame::onToolAlignRight()
- {
- ui.graphicsView->getScene()->BlockAlignRight();
- }
- /// <summary>
- /// 功能块底对齐
- /// </summary>
- void WindowAppPouFrame::onToolAlignBottom()
- {
- ui.graphicsView->getScene()->BlockAlignBottom();
- }
- /// <summary>
- /// Undo
- /// </summary>
- void WindowAppPouFrame::onToolUndo()
- {
- // vDebug() << "WindowAppPouFrame::onToolUndo";
- ((WindowAppPouScene*)ui.graphicsView->getScene())->m_CommandManager.undo();
- }
- /// <summary>
- /// Redo
- /// </summary>
- void WindowAppPouFrame::onToolRedo()
- {
- // vDebug() << "WindowAppPouFrame::onToolRedo";
- ((WindowAppPouScene*)ui.graphicsView->getScene())->m_CommandManager.redo();
- }
- /// <summary>
- /// Option
- /// </summary>
- void WindowAppPouFrame::onToolOption()
- {
- vDebug() << "WindowAppPouFrame::onToolOption";
- }
- /// <summary>
- /// 执行一轮
- /// </summary>
- void WindowAppPouFrame::onToolRunOnce()
- {
- QFuture<void> Future = QtConcurrent::run(this, &WindowAppPouFrame::ToolRunOnce);
- }
- /// <summary>
- /// 单步执行
- /// </summary>
- void WindowAppPouFrame::onToolSingleStep()
- {
- QFuture<void> Future = QtConcurrent::run(this, &WindowAppPouFrame::ToolSingleStep);
- }
- /// <summary>
- /// 线程函数 - 执行一轮
- /// </summary>
- void WindowAppPouFrame::ToolRunOnce()
- {
- // 通过名字找到对应的Pou
- POU* pou = g_pPouManager->getPouByName(m_strTitle);
- // 执行所有工具,执行一轮
- pou->ToolExecuteAll();
- }
- /// <summary>
- /// 线程函数 - 单步执行
- /// </summary>
- void WindowAppPouFrame::ToolSingleStep()
- {
- // 通过名字找到对应的Pou
- POU* pou = g_pPouManager->getPouByName(m_strTitle);
- // 单步执行
- pou->ToolExecuteSingleStep();
- }
- /// <summary>
- /// 接收键盘消息
- /// </summary>
- /// <param name="event"></param>
- void WindowAppPouFrame::keyPressEvent(QKeyEvent* event)
- {
- //先检测Ctrl键是否按下
- if (QApplication::keyboardModifiers() == Qt::ControlModifier)
- {
- WindowAppPouScene* pScene = (WindowAppPouScene*)ui.graphicsView->getScene();
- if (pScene == nullptr)
- {
- return;
- }
- //检测 Z 键,并执行撤销动作
- if (event->key() == Qt::Key_Z)
- {
- if (pScene->m_CommandManager.canUndo())
- {
- pScene->m_CommandManager.undo();
- }
- }
- // 检测 Y 键,并执行反撤销动作
- if (event->key() == Qt::Key_Y)
- {
- if (pScene->m_CommandManager.canRedo())
- {
- pScene->m_CommandManager.redo();
- }
- }
- }
- }
- /// <summary>
- /// 在界面中添加新的变量(from序列化文件)
- /// </summary>
- /// <param name="pNewVariable"></param>
- void WindowAppPouFrame::addNewVariable(VARIABLE* pNewVariable)
- {
- // 2022-2-15增加,Pou内部变量不需要显示在界面中
- if (pNewVariable->bShow)
- {
- // 界面中添加新的一行
- ui.tableVariable->insertTableLine(
- pNewVariable->bSerialized,
- pNewVariable->strName,
- pNewVariable->strFullName,
- Utility::getTypeString(pNewVariable->value.type),
- Utility::getValueString(pNewVariable->value.Ptr, pNewVariable->value.type),
- pNewVariable->strComment
- );
- // 绑定新的变量和界面对应关系,方便变更之后及时发送通知
- g_pGvlManager->bindUIAndVariable(ui.tableVariable, pNewVariable->strFullName);
- }
- }
- ///// <summary>
- ///// 在界面和数据结构中添加新的TOOL(from序列化文件)
- ///// </summary>
- ///// <param name="newTool"></param>
- //void WindowAppPouFrame::addNewTool(TOOL* pNewTool, QPointF pos)
- //{
- // ui.graphicsView->addToolDirectly(pNewTool, pos);
- //}
- ///// <summary>
- ///// 在界面中添加新的Link(from序列化文件)
- ///// </summary>
- ///// <param name="strSrcInf"></param>
- ///// <param name="strDstInf"></param>
- //void WindowAppPouFrame::addNewLink(const QString& strStartInf, const QString& strEndInf, LINK_MODE linkMode)
- //{
- // ui.graphicsView->addLinkDirectly(strStartInf, strEndInf, linkMode);
- //}
- /// <summary>
- /// 将功能块的Debug 数据写入UI
- /// </summary>
- /// <param name="data"></param>
- void WindowAppPouFrame::UpdataDebugData(DebugData data)
- {
- ui.pouDebugView->UpdataDebugData(data);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="event"></param>
- void WindowAppPouFrame::resizeEvent(QResizeEvent* event)
- {
- Q_UNUSED(event);
- if (m_pNavView)
- {
- m_pNavView->move(ui.graphicsView->width() - m_pNavView->width() - 12, ui.graphicsView->height() - m_pNavView->height() + 12);
- }
- }
- /// <summary>
- /// 拖动伸缩滑块的时候,调整鸟瞰图窗口位置
- /// </summary>
- /// <param name=""></param>
- /// <param name=""></param>
- void WindowAppPouFrame::slotSplitterMoved(int pos, int indext)
- {
- Q_UNUSED(pos);
- Q_UNUSED(indext);
- if (m_pNavView)
- {
- m_pNavView->move(ui.graphicsView->width() - m_pNavView->width() - 12, ui.graphicsView->height() - m_pNavView->height() + 12);
- }
- }
- /// <summary>
- /// 鼠标移入的时候,显示鸟瞰图
- /// </summary>
- /// <param name="event"></param>
- void WindowAppPouFrame::enterEvent(QEvent* event)
- {
- Q_UNUSED(event);
- if (m_pNavView)
- {
- m_pNavView->setOpacity(1);
- }
- }
- /// <summary>
- /// 鼠标移出的时候,隐藏鸟瞰图
- /// </summary>
- /// <param name="event"></param>
- void WindowAppPouFrame::leaveEvent(QEvent* event)
- {
- Q_UNUSED(event);
- if (m_pNavView)
- {
- m_pNavView->setOpacity(0);
- }
- }
- /// <summary>
- /// 序列化
- /// </summary>
- /// <param name="out"></param>
- /// <param name="pFrame"></param>
- /// <returns></returns>
- QDataStream& operator<<(QDataStream& out, const WindowAppPouFrame* pFrame)
- {
- if (pFrame != nullptr)
- {
- int paranum;//参数数量
- paranum = 2;
- out << paranum;//先保存参数数量
- out << (int)1 << pFrame->ui.splitter->sizes();
- out << (int)2 << pFrame->ui.pouDebugView->getSplitter()->sizes();
- }
- // Error
- else
- {
- vDebug() << "[Error] WindowAppPouFrame - operator<< failed, pFrame == nullptr";
- }
- return out;
- }
- /// <summary>
- /// 反序列化
- /// </summary>
- /// <param name="in"></param>
- /// <param name="pFrame"></param>
- /// <returns></returns>
- QDataStream& operator>>(QDataStream& in, WindowAppPouFrame* pFrame)
- {
- if (pFrame != nullptr)
- {
- QList<int> splitters;
- QList<int> splittersDdebugView;
- int paranum;//参数数量
- int para;
- in >> paranum;//读取参数数量
- for (int i = 0; i < paranum; i++)
- {
- in >> para;
- switch (para)
- {
- case 1: in >> splitters; break;
- case 2: in >> splittersDdebugView; break;
- default:
- {
- vWarning() << "Serialized(In) Error";
-
- }
- break;
- }
- }
- // 界面中设置Splitter
- pFrame->ui.splitter->setSizes(splitters);
- pFrame->ui.pouDebugView->getSplitter()->setSizes(splittersDdebugView);
- }
- // Error
- else
- {
- vDebug() << "[Error] WindowAppPouFrame - operator>> failed, pFrame == nullptr";
- }
- return in;
- }
- /// <summary>
- /// 响应Paint事件为了刷新Undo菜单启用禁用(TODO:暂时没有找到更好的位置)
- /// </summary>
- void WindowAppPouFrame::paintEvent(QPaintEvent* event)
- {
- Q_UNUSED(event);
- // 刷新Undo菜单
- this->refreshUndoMenu();
- }
- /// <summary>
- /// 刷新Undo/Redo按钮
- /// </summary>
- void WindowAppPouFrame::refreshUndoMenu()
- {
- if (actionUndo != nullptr)
- {
- WindowAppPouScene* pScene = (WindowAppPouScene*)ui.graphicsView->getScene();
- actionUndo->setEnabled(pScene->m_CommandManager.canUndo());
- actionRedo->setEnabled(pScene->m_CommandManager.canRedo());
- }
- }
|