Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

675 righe
21 KiB

  1. #include "hmidocument.h"
  2. #include "graphicsitems.h"
  3. #include <QGraphicsItem>
  4. #include <QGraphicsSceneHoverEvent>
  5. #include <QMouseEvent>
  6. #include <QMenu>
  7. #include <QAction>
  8. #include <QDataStream>
  9. #include <QColorDialog>
  10. #include <QDialog>
  11. #include <QFormLayout>
  12. #include <QLineEdit>
  13. #include <QPushButton>
  14. #include <QDialogButtonBox>
  15. #include <QMimeData>
  16. #include <QDragEnterEvent>
  17. #include <QDropEvent>
  18. #include <QDebug>
  19. #include <QFileInfo>
  20. #include <QVBoxLayout>
  21. #include <QJsonArray>
  22. #include <QJsonDocument>
  23. #include <QJsonObject>
  24. #include<QSpinBox>
  25. HMIDocument::HMIDocument(QWidget *parent)
  26. : BaseDocument(HMI, parent),
  27. m_title("未命名HMI"),
  28. m_canDrawEllipse(false),
  29. m_canDrawRectangle(false),
  30. m_lastPastePos(0, 0)
  31. {
  32. // 创建绘图场景 - 固定大小
  33. m_scene = new QGraphicsScene(this);
  34. m_scene->setSceneRect(0, 0, 1000, 600); // 固定画布尺寸
  35. m_scene->setBackgroundBrush(QBrush(Qt::lightGray));
  36. // 创建视图 - 关键修改:使用滚动区域包装
  37. m_scrollArea = new QScrollArea(this);
  38. m_scrollArea->setWidgetResizable(false); // 禁止内容自动调整大小
  39. //m_scrollArea->setFrameShape(QFrame::NoFrame); // 无边框
  40. // 创建真正的视图部件
  41. m_view = new QGraphicsView(m_scene, this);
  42. m_view->setRenderHint(QPainter::Antialiasing);
  43. m_view->setDragMode(QGraphicsView::RubberBandDrag);
  44. m_view->setAcceptDrops(true);
  45. m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏自身滚动条
  46. m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  47. // 关键:视图固定大小与场景匹配
  48. m_view->setMinimumSize(1000, 600);
  49. m_view->setMaximumSize(1000, 600);
  50. m_view->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  51. m_view->viewport()->installEventFilter(this);
  52. // 添加视图到滚动区域
  53. m_scrollArea->setWidget(m_view);
  54. m_scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  55. // 设置主布局
  56. auto layout = new QVBoxLayout(this);
  57. layout->setContentsMargins(0, 0, 0, 0);
  58. layout->addWidget(m_scrollArea);
  59. setLayout(layout);
  60. }
  61. HMIDocument::~HMIDocument()
  62. {
  63. }
  64. // 事件过滤器(处理绘图、拖拽等事件)
  65. bool HMIDocument::eventFilter(QObject *obj, QEvent *event)
  66. {
  67. if (obj != m_view->viewport())
  68. {
  69. return QWidget::eventFilter(obj, event);
  70. }
  71. // 鼠标按下事件(绘制图形)
  72. if (event->type() == QEvent::MouseButtonPress)
  73. {
  74. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
  75. setModified(true);
  76. if (mouseEvent->button() == Qt::RightButton)
  77. {
  78. showContextMenu(mouseEvent->globalPos());// 右键菜单
  79. return true;
  80. }
  81. if (mouseEvent->button() == Qt::LeftButton)
  82. {
  83. QPointF scenePos = m_view->mapToScene(mouseEvent->pos());
  84. QGraphicsItem *item = m_scene->itemAt(scenePos, m_view->transform());
  85. // 如果点击空白区域且有绘制标志,创建图形
  86. if (!item) {
  87. if (m_canDrawEllipse)
  88. {
  89. createShape("ellipse", scenePos);
  90. resetDrawFlags();
  91. }
  92. else if (m_canDrawRectangle)
  93. {
  94. createShape("rectangle", scenePos);
  95. resetDrawFlags();
  96. }
  97. }
  98. }
  99. }
  100. // 拖拽事件(从工具栏拖拽绘制)
  101. if (event->type() == QEvent::DragEnter)
  102. {
  103. QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>(event);
  104. dragEvent->acceptProposedAction();
  105. return true;
  106. }
  107. if (event->type() == QEvent::DragMove)
  108. {
  109. static_cast<QDragMoveEvent*>(event)->acceptProposedAction();
  110. return true;
  111. }
  112. if (event->type() == QEvent::Drop)
  113. {
  114. QDropEvent *dropEvent = static_cast<QDropEvent*>(event);
  115. const QMimeData *mimeData = dropEvent->mimeData();
  116. QPointF scenePos = m_view->mapToScene(dropEvent->pos());
  117. // 使用QMimeData
  118. if (mimeData && mimeData->hasText())
  119. {
  120. createShape(mimeData->text(), scenePos);
  121. resetDrawFlags();//重置防止拖拽后再次点击生成
  122. }
  123. dropEvent->acceptProposedAction();
  124. return true;
  125. }
  126. return QWidget::eventFilter(obj, event);
  127. }
  128. void HMIDocument::createShape(const QString& type, const QPointF &pos)
  129. {
  130. m_scene->clearSelection();
  131. if (type == "指示灯" || type == "ellipse")
  132. {
  133. ResizableEllipse *ellipse = new ResizableEllipse(pos.x(), pos.y(), 50, 50);
  134. ellipse->setBrush(QBrush(Qt::red));
  135. ellipse->setPen(QPen(Qt::black, 1));
  136. m_scene->addItem(ellipse);
  137. ellipse->setSelected(true);
  138. }
  139. else if (type == "按钮" || type == "rectangle")
  140. {
  141. ResizableRectangle *rect = new ResizableRectangle(pos.x(), pos.y(), 100, 50);
  142. rect->setBrush(QBrush(Qt::yellow));
  143. rect->setPen(QPen(Qt::black, 1));
  144. m_scene->addItem(rect);
  145. rect->setSelected(true);
  146. }
  147. setModified(true);
  148. }
  149. // 重置绘制标志
  150. void HMIDocument::resetDrawFlags()
  151. {
  152. m_canDrawEllipse = false;
  153. m_canDrawRectangle = false;
  154. }
  155. // 右键菜单
  156. void HMIDocument::showContextMenu(QPoint globalPos)
  157. {
  158. QPoint viewportPos = m_view->mapFromGlobal(globalPos);
  159. QPointF scenePos = m_view->mapToScene(viewportPos);
  160. QGraphicsItem *clickedItem = m_scene->itemAt(scenePos, m_view->transform());
  161. QMenu menu(this);
  162. if (!clickedItem)
  163. {
  164. // 空白区域:仅显示粘贴
  165. QAction *pasteAction = menu.addAction("粘贴");
  166. pasteAction->setEnabled(!m_copiedItemsData.isEmpty());
  167. connect(pasteAction, &QAction::triggered, this, &HMIDocument::pasteItems);
  168. }
  169. else
  170. {
  171. // 选中图形:显示基础菜单
  172. QAction *propAction = menu.addAction("属性");
  173. QAction *copyAction = menu.addAction("复制");
  174. QAction *pasteAction = menu.addAction("粘贴");
  175. QAction *deleteAction = menu.addAction("删除");
  176. pasteAction->setEnabled(!m_copiedItemsData.isEmpty());
  177. connect(propAction, &QAction::triggered, this, &HMIDocument::showItemProperties);
  178. connect(copyAction, &QAction::triggered, this, &HMIDocument::copySelectedItems);
  179. connect(pasteAction, &QAction::triggered, this, &HMIDocument::pasteItems);
  180. connect(deleteAction, &QAction::triggered, this, &HMIDocument::deleteSelectedItems);
  181. // 仅对按钮(矩形)显示ON/OFF选项,指示灯(椭圆)不显示
  182. if (dynamic_cast<ResizableRectangle*>(clickedItem)) {
  183. QAction *onAction = menu.addAction("置为ON");
  184. QAction *offAction = menu.addAction("置为OFF");
  185. connect(onAction, &QAction::triggered, [=]() {
  186. if (auto rect = dynamic_cast<ResizableRectangle*>(clickedItem)) {
  187. rect->setBrush(rect->pressedColor());
  188. }
  189. });
  190. connect(offAction, &QAction::triggered, [=]() {
  191. if (auto rect = dynamic_cast<ResizableRectangle*>(clickedItem)) {
  192. rect->setBrush(rect->releasedColor());
  193. }
  194. });
  195. }
  196. }
  197. menu.exec(globalPos + QPoint(10, 10));
  198. }
  199. // 复制选中项
  200. void HMIDocument::copySelectedItems()
  201. {
  202. m_copiedItemsData.clear();
  203. QList<QGraphicsItem*> selectedItems = m_scene->selectedItems();
  204. if (selectedItems.isEmpty()) return;
  205. foreach (QGraphicsItem *item, selectedItems)
  206. {
  207. m_copiedItemsData.append(serializeItem(item));
  208. }
  209. m_lastPastePos = selectedItems.first()->pos();
  210. setModified(true);
  211. }
  212. // 粘贴项
  213. void HMIDocument::pasteItems()
  214. {
  215. if (m_copiedItemsData.isEmpty()) return;
  216. QPointF offset(20, 20);
  217. m_lastPastePos += offset;
  218. m_scene->clearSelection();
  219. foreach (const QByteArray &itemData, m_copiedItemsData)
  220. {
  221. QGraphicsItem *newItem = deserializeItem(itemData);
  222. if (newItem)
  223. {
  224. m_scene->addItem(newItem);
  225. newItem->setPos(m_lastPastePos);
  226. newItem->setSelected(true);
  227. }
  228. }
  229. setModified(true);
  230. }
  231. // 删除选中项
  232. void HMIDocument::deleteSelectedItems()
  233. {
  234. QList<QGraphicsItem*> selectedItems = m_scene->selectedItems();
  235. foreach (QGraphicsItem *item, selectedItems) {
  236. m_scene->removeItem(item);
  237. delete item;
  238. }
  239. setModified(true);
  240. }
  241. // 显示属性对话框
  242. // 在HMIDocument::showItemProperties()方法中替换相关代码
  243. void HMIDocument::showItemProperties()
  244. {
  245. QList<QGraphicsItem*> selectedItems = m_scene->selectedItems();
  246. if (selectedItems.isEmpty()) return;
  247. QGraphicsItem *item = selectedItems.first();
  248. // 将QGraphicsItem转换为NamedItem
  249. NamedItem *namedItem = dynamic_cast<NamedItem*>(item);
  250. if (!namedItem) return;
  251. QDialog dialog(this);
  252. dialog.setWindowTitle("属性设置");
  253. QFormLayout *form = new QFormLayout(&dialog);
  254. // 线圈地址输入 - 使用SpinBox替代LineEdit
  255. QSpinBox *coilAddrSpin = new QSpinBox();
  256. coilAddrSpin->setRange(0, 4000); // 设置PLC线圈地址常见范围
  257. // 尝试从名称解析现有地址(如果之前用数字作为名称)
  258. bool isNumber;
  259. int addr = namedItem->name().toInt(&isNumber);
  260. if (isNumber) {
  261. coilAddrSpin->setValue(addr);
  262. }
  263. // 颜色选择(保持不变)
  264. QColor tempColor1, tempColor2;
  265. QPushButton *colorBtn1 = new QPushButton;
  266. QPushButton *colorBtn2 = new QPushButton;
  267. if (auto ellipse = dynamic_cast<ResizableEllipse*>(item)) {
  268. tempColor1 = ellipse->onColor();
  269. tempColor2 = ellipse->offColor();
  270. form->addRow("ON颜色:", colorBtn1);
  271. form->addRow("OFF颜色:", colorBtn2);
  272. } else if (auto rect = dynamic_cast<ResizableRectangle*>(item)) {
  273. tempColor1 = rect->pressedColor();
  274. tempColor2 = rect->releasedColor();
  275. form->addRow("按下颜色:", colorBtn1);
  276. form->addRow("释放颜色:", colorBtn2);
  277. }
  278. // 初始化颜色按钮(保持不变)
  279. colorBtn1->setStyleSheet("background-color:" + tempColor1.name());
  280. colorBtn2->setStyleSheet("background-color:" + tempColor2.name());
  281. // 颜色选择对话框(保持不变)
  282. connect(colorBtn1, &QPushButton::clicked, [&]() {
  283. QColor c = QColorDialog::getColor(tempColor1, &dialog);
  284. if (c.isValid()) {
  285. tempColor1 = c;
  286. colorBtn1->setStyleSheet("background-color:" + c.name());
  287. }
  288. });
  289. connect(colorBtn2, &QPushButton::clicked, [&]() {
  290. QColor c = QColorDialog::getColor(tempColor2, &dialog);
  291. if (c.isValid()) {
  292. tempColor2 = c;
  293. colorBtn2->setStyleSheet("background-color:" + c.name());
  294. }
  295. });
  296. // 布局组装(将名称输入替换为线圈地址)
  297. form->addRow("线圈地址:", coilAddrSpin); // 这里是关键修改
  298. QDialogButtonBox *btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  299. form->addRow(btnBox);
  300. connect(btnBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
  301. connect(btnBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
  302. // 应用属性(使用SpinBox的值作为地址)
  303. if (dialog.exec() == QDialog::Accepted) {
  304. setModified(true);
  305. // 将SpinBox的值转换为字符串保存到名称属性
  306. namedItem->setName(QString::number(coilAddrSpin->value()));
  307. if (auto ellipse = dynamic_cast<ResizableEllipse*>(item)) {
  308. ellipse->setOnColor(tempColor1);
  309. ellipse->setOffColor(tempColor2);
  310. } else if (auto rect = dynamic_cast<ResizableRectangle*>(item)) {
  311. rect->setPressedColor(tempColor1);
  312. rect->setReleasedColor(tempColor2);
  313. }
  314. item->update();
  315. }
  316. }
  317. // 序列化图形项(用于复制粘贴)
  318. QByteArray HMIDocument::serializeItem(QGraphicsItem *item)
  319. {
  320. QByteArray data;
  321. QDataStream stream(&data, QIODevice::WriteOnly);
  322. // 基础信息
  323. stream << item->type();
  324. stream << item->pos();
  325. stream << item->flags();
  326. stream << item->transform();
  327. stream << item->isVisible();
  328. // 形状信息
  329. if (auto shape = dynamic_cast<QAbstractGraphicsShapeItem*>(item))
  330. {
  331. stream << shape->pen();
  332. stream << shape->brush();
  333. stream << shape->boundingRect();
  334. }
  335. // 具体图形信息
  336. if (auto rect = dynamic_cast<ResizableRectangle*>(item))
  337. {
  338. stream << rect->rect();
  339. stream << rect->pressedColor();
  340. stream << rect->releasedColor();
  341. stream << rect->name();
  342. } else if (auto ellipse = dynamic_cast<ResizableEllipse*>(item))
  343. {
  344. stream << ellipse->rect();
  345. stream << ellipse->onColor();
  346. stream << ellipse->offColor();
  347. stream << ellipse->name();
  348. }
  349. return data;
  350. }
  351. // 反序列化图形项(用于粘贴)
  352. QGraphicsItem *HMIDocument::deserializeItem(const QByteArray &data)
  353. {
  354. QDataStream stream(data);
  355. int type;
  356. QPointF pos;
  357. QGraphicsItem::GraphicsItemFlags flags;
  358. QTransform transform;
  359. bool visible;
  360. stream >> type >> pos >> flags >> transform >> visible;
  361. QGraphicsItem *item = nullptr;
  362. if (type == QGraphicsRectItem::Type) {
  363. QPen pen;
  364. QBrush brush;
  365. QRectF boundRect;
  366. QRectF rect;
  367. QColor pressedColor, releasedColor;
  368. QString name;
  369. stream >> pen >> brush >> boundRect >> rect >> pressedColor >> releasedColor >> name;
  370. ResizableRectangle *rectItem = new ResizableRectangle(0, 0, rect.width(), rect.height());
  371. rectItem->setPen(pen);
  372. rectItem->setBrush(brush);
  373. rectItem->setPressedColor(pressedColor);
  374. rectItem->setReleasedColor(releasedColor);
  375. rectItem->setName(name);
  376. item = rectItem;
  377. } else if (type == QGraphicsEllipseItem::Type) {
  378. QPen pen;
  379. QBrush brush;
  380. QRectF boundRect;
  381. QRectF rect;
  382. QColor onColor, offColor;
  383. QString name;
  384. stream >> pen >> brush >> boundRect >> rect >> onColor >> offColor >> name;
  385. ResizableEllipse *ellipseItem = new ResizableEllipse(0, 0, rect.width(), rect.height());
  386. ellipseItem->setPen(pen);
  387. ellipseItem->setBrush(brush);
  388. ellipseItem->setOnColor(onColor);
  389. ellipseItem->setOffColor(offColor);
  390. ellipseItem->setName(name);
  391. item = ellipseItem;
  392. }
  393. if (item) {
  394. item->setFlags(flags);
  395. item->setTransform(transform);
  396. item->setVisible(visible);
  397. }
  398. return item;
  399. }
  400. void HMIDocument::startDrawingEllipse()
  401. {
  402. m_canDrawEllipse = true;
  403. m_canDrawRectangle = false;
  404. }
  405. void HMIDocument::startDrawingRectangle()
  406. {
  407. m_canDrawEllipse = false;
  408. m_canDrawRectangle = true;
  409. }
  410. bool HMIDocument::saveToFile(const QString &filePath)
  411. {
  412. QFile file(filePath);
  413. if (!file.open(QIODevice::WriteOnly)) {
  414. qWarning() << "无法打开文件进行写入:" << filePath;
  415. return false;
  416. }
  417. // 创建JSON文档结构
  418. QJsonObject docObject;
  419. docObject["title"] = m_title;
  420. docObject["sceneRect"] = QJsonArray({
  421. m_scene->sceneRect().x(),
  422. m_scene->sceneRect().y(),
  423. m_scene->sceneRect().width(),
  424. m_scene->sceneRect().height()
  425. });
  426. docObject["backgroundColor"] = m_scene->backgroundBrush().color().name();
  427. // 序列化所有图形项
  428. QJsonArray itemsArray;
  429. foreach (QGraphicsItem *item, m_scene->items()) {
  430. QJsonObject itemJson = itemToJson(item);
  431. if (!itemJson.isEmpty()) {
  432. itemsArray.append(itemJson);
  433. }
  434. }
  435. docObject["items"] = itemsArray;
  436. // 写入文件
  437. QJsonDocument doc(docObject);
  438. file.write(doc.toJson());
  439. file.close();
  440. // 更新文档状态
  441. setFilePath(filePath);
  442. setModified(false);
  443. QFileInfo fileInfo(filePath);
  444. setTitle(fileInfo.baseName());
  445. return true;
  446. }
  447. // 从文件加载文档
  448. bool HMIDocument::loadFromFile(const QString &filePath)
  449. {
  450. QFile file(filePath);
  451. if (!file.open(QIODevice::ReadOnly)) {
  452. qWarning() << "无法打开文件进行读取:" << filePath;
  453. return false;
  454. }
  455. // 读取JSON文档
  456. QByteArray data = file.readAll();
  457. QJsonDocument doc = QJsonDocument::fromJson(data);
  458. if (doc.isNull()) {
  459. qWarning() << "无效的JSON文档:" << filePath;
  460. return false;
  461. }
  462. // 解析文档
  463. QJsonObject docObject = doc.object();
  464. m_title = docObject["title"].toString();
  465. // 设置场景属性
  466. QJsonArray sceneRectArray = docObject["sceneRect"].toArray();
  467. if (sceneRectArray.size() == 4) {
  468. QRectF sceneRect(
  469. sceneRectArray[0].toDouble(),
  470. sceneRectArray[1].toDouble(),
  471. sceneRectArray[2].toDouble(),
  472. sceneRectArray[3].toDouble()
  473. );
  474. m_scene->setSceneRect(sceneRect);
  475. }
  476. if (docObject.contains("backgroundColor")) {
  477. QColor bgColor(docObject["backgroundColor"].toString());
  478. m_scene->setBackgroundBrush(QBrush(bgColor));
  479. }
  480. // 清除现有内容
  481. m_scene->clear();
  482. // 加载所有图形项
  483. QJsonArray itemsArray = docObject["items"].toArray();
  484. foreach (QJsonValue itemValue, itemsArray) {
  485. QJsonObject itemJson = itemValue.toObject();
  486. QGraphicsItem *item = jsonToItem(itemJson);
  487. if (item) {
  488. m_scene->addItem(item);
  489. }
  490. }
  491. // 更新文档状态
  492. setFilePath(filePath);
  493. setModified(false);
  494. return true;
  495. }
  496. // 将图形项转换为JSON对象
  497. QJsonObject HMIDocument::itemToJson(QGraphicsItem *item)
  498. {
  499. QJsonObject json;
  500. // 基础属性
  501. json["type"] = item->type();
  502. json["x"] = item->x();
  503. json["y"] = item->y();
  504. json["zValue"] = item->zValue();
  505. json["visible"] = item->isVisible();
  506. // 具体图形项属性
  507. if (auto ellipse = dynamic_cast<ResizableEllipse*>(item)) {
  508. json["itemType"] = "ellipse";
  509. json["rect"] = QJsonArray({
  510. ellipse->rect().x(),
  511. ellipse->rect().y(),
  512. ellipse->rect().width(),
  513. ellipse->rect().height()
  514. });
  515. json["onColor"] = ellipse->onColor().name();
  516. json["offColor"] = ellipse->offColor().name();
  517. json["currentColor"] = ellipse->brush().color().name();
  518. json["penColor"] = ellipse->pen().color().name();
  519. json["penWidth"] = ellipse->pen().width();
  520. json["name"] = ellipse->name();
  521. }
  522. else if (auto rect = dynamic_cast<ResizableRectangle*>(item)) {
  523. json["itemType"] = "rectangle";
  524. json["rect"] = QJsonArray({
  525. rect->rect().x(),
  526. rect->rect().y(),
  527. rect->rect().width(),
  528. rect->rect().height()
  529. });
  530. json["pressedColor"] = rect->pressedColor().name();
  531. json["releasedColor"] = rect->releasedColor().name();
  532. json["currentColor"] = rect->brush().color().name();
  533. json["penColor"] = rect->pen().color().name();
  534. json["penWidth"] = rect->pen().width();
  535. json["name"] = rect->name();
  536. }
  537. return json;
  538. }
  539. // 从JSON对象创建图形项
  540. QGraphicsItem *HMIDocument::jsonToItem(const QJsonObject &json)
  541. {
  542. QString itemType = json["itemType"].toString();
  543. QGraphicsItem *item = nullptr;
  544. if (itemType == "ellipse") {
  545. QJsonArray rectArray = json["rect"].toArray();
  546. if (rectArray.size() != 4) return nullptr;
  547. ResizableEllipse *ellipse = new ResizableEllipse(
  548. rectArray[0].toDouble(),
  549. rectArray[1].toDouble(),
  550. rectArray[2].toDouble(),
  551. rectArray[3].toDouble()
  552. );
  553. ellipse->setOnColor(QColor(json["onColor"].toString()));
  554. ellipse->setOffColor(QColor(json["offColor"].toString()));
  555. ellipse->setBrush(QColor(json["currentColor"].toString()));
  556. ellipse->setPen(QPen(
  557. QColor(json["penColor"].toString()),
  558. json["penWidth"].toDouble()
  559. ));
  560. ellipse->setName(json["name"].toString());
  561. item = ellipse;
  562. }
  563. else if (itemType == "rectangle") {
  564. QJsonArray rectArray = json["rect"].toArray();
  565. if (rectArray.size() != 4) return nullptr;
  566. ResizableRectangle *rect = new ResizableRectangle(
  567. rectArray[0].toDouble(),
  568. rectArray[1].toDouble(),
  569. rectArray[2].toDouble(),
  570. rectArray[3].toDouble()
  571. );
  572. rect->setPressedColor(QColor(json["pressedColor"].toString()));
  573. rect->setReleasedColor(QColor(json["releasedColor"].toString()));
  574. rect->setBrush(QColor(json["currentColor"].toString()));
  575. rect->setPen(QPen(
  576. QColor(json["penColor"].toString()),
  577. json["penWidth"].toDouble()
  578. ));
  579. rect->setName(json["name"].toString());
  580. item = rect;
  581. }
  582. // 设置基础属性
  583. if (item) {
  584. item->setX(json["x"].toDouble());
  585. item->setY(json["y"].toDouble());
  586. item->setZValue(json["zValue"].toDouble());
  587. item->setVisible(json["visible"].toBool());
  588. }
  589. return item;
  590. }
  591. QString HMIDocument::title() const { return m_title; }
  592. void HMIDocument::setTitle(const QString &title) { m_title = title; }
  593. QGraphicsView *HMIDocument::view() const { return m_view; }
  594. QGraphicsScene *HMIDocument::scene() const { return m_scene; }
  595. void HMIDocument::setDrawEllipse(bool enable) { m_canDrawEllipse = enable; }
  596. void HMIDocument::setDrawRectangle(bool enable) { m_canDrawRectangle = enable; }
  597. void HMIDocument::markModified() { setModified(true); }