diff --git a/IntegratedPlatform/IntegratedPlatform.pro.user b/IntegratedPlatform/IntegratedPlatform.pro.user index 7a0b1c7..13aadfc 100644 --- a/IntegratedPlatform/IntegratedPlatform.pro.user +++ b/IntegratedPlatform/IntegratedPlatform.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/IntegratedPlatform/hmiwidget.h b/IntegratedPlatform/hmiwidget.h index 52da599..91b5ba5 100644 --- a/IntegratedPlatform/hmiwidget.h +++ b/IntegratedPlatform/hmiwidget.h @@ -30,12 +30,43 @@ protected: class ResizableRectangle : public ResizableShape { public: ResizableRectangle(qreal x, qreal y, qreal w, qreal h); -}; + QColor pressedColor() const { return m_pressedColor; } + void setPressedColor(const QColor& color) { m_pressedColor = color; } + + QColor releasedColor() const { return m_releasedColor; } + void setReleasedColor(const QColor& color) { m_releasedColor = color; } + + QString name() const { return m_name; } + void setName(const QString& name) { m_name = name; } +private: + QColor m_pressedColor = Qt::green; // 按钮按下时的颜色 + QColor m_releasedColor = Qt::yellow; // 按钮松开时的颜色 + QString m_name = "按钮"; // 默认名称 +}; +class NamedItem { +public: + virtual QString name() const = 0; + virtual void setName(const QString& name) = 0; + virtual ~NamedItem() = default; +}; // 可调整大小的椭圆 class ResizableEllipse : public ResizableShape { public: ResizableEllipse(qreal x, qreal y, qreal w, qreal h); + QColor onColor() const { return m_onColor; } + void setOnColor(const QColor& color) { m_onColor = color; } + + QColor offColor() const { return m_offColor; } + void setOffColor(const QColor& color) { m_offColor = color; } + + QString name() const { return m_name; } + void setName(const QString& name) { m_name = name; } + +private: + QColor m_onColor = Qt::green; // 默认开状态颜色 + QColor m_offColor = Qt::red; // 默认关状态颜色 + QString m_name = "指示灯"; // 默认名称 }; #endif // HMIWIDGET_H diff --git a/IntegratedPlatform/mainwindow.cpp b/IntegratedPlatform/mainwindow.cpp index fcd025c..c3b5c0e 100644 --- a/IntegratedPlatform/mainwindow.cpp +++ b/IntegratedPlatform/mainwindow.cpp @@ -5,6 +5,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) @@ -29,7 +35,6 @@ MainWindow::MainWindow(QWidget *parent) ui->actiondelete->setShortcut(QKeySequence::Delete);//设置快捷键 ui->actioncopy->setShortcut(QKeySequence::Copy); ui->actionpaste->setShortcut(QKeySequence::Paste); - ui->treeWidget->topLevelItem(0)->setIcon(0, QIcon("../two/IntegratedPlatform/images/T-常开触点-01.png")); ui->treeWidget->topLevelItem(1)->setIcon(0, QIcon("../two/IntegratedPlatform/images/T-常闭触点-01-01.png")); ui->treeWidget->topLevelItem(2)->setIcon(0, QIcon("../two/IntegratedPlatform/images/大于等于.png")); @@ -255,7 +260,71 @@ void MainWindow::onActionPasteTriggered() } } } +//属性功能 +void MainWindow::onActionPropertiesTriggered() +{ + QList selectedItems = scene->selectedItems(); + if (selectedItems.isEmpty()) return; + QGraphicsItem* selectedItem = selectedItems.first(); + QDialog dialog(this);// 创建对话框 + dialog.setWindowTitle("属性设置"); + QFormLayout* formLayout = new QFormLayout(&dialog); + + QColor tempOnColor = Qt::green;//临时变量存储选择的颜色 + QColor tempOffColor = Qt::red;//临时变量存储选择的颜色 + + QLineEdit* nameEdit = new QLineEdit(&dialog);//对象输入框 + if (auto namedItem = dynamic_cast(selectedItem)) + { + nameEdit->setText(namedItem->name()); + } + + // 开状态颜色选择 + QPushButton* onColorBtn = new QPushButton("", &dialog); + onColorBtn->setStyleSheet("background-color:" + tempOnColor.name());; + connect(onColorBtn, &QPushButton::clicked, [&]() + { + QColor newColor = QColorDialog::getColor(tempOnColor, &dialog, "选择ON状态颜色"); + tempOnColor = newColor; + onColorBtn->setStyleSheet("background-color:" + tempOnColor.name());; + }); + // 关状态颜色选择 + QPushButton* offColorBtn = new QPushButton("", &dialog); + offColorBtn->setStyleSheet("background-color:"+tempOffColor.name()); + connect(offColorBtn, &QPushButton::clicked, [&]() + { + QColor newColor = QColorDialog::getColor(tempOffColor, &dialog, "选择OFF状态颜色"); + tempOffColor = newColor; + offColorBtn->setStyleSheet("background-color:"+tempOffColor.name()); + }); + formLayout->addRow("对象:", nameEdit); + formLayout->addRow("ON颜色:", onColorBtn); + formLayout->addRow("OFF颜色:", offColorBtn); + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); + formLayout->addRow(buttonBox); + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + if (dialog.exec() == QDialog::Accepted)//显示对话框并应用更改 + { + QString newName = nameEdit->text();// 应用新属性到图形项 + if (auto ellipse = dynamic_cast(selectedItem)) + { + ellipse->setOnColor(tempOnColor); + ellipse->setOffColor(tempOffColor); + ellipse->setName(newName); + ellipse->setBrush(tempOnColor); // 应用开状态颜色 + } + else if (auto rect = dynamic_cast(selectedItem)) + { + rect->setPressedColor(tempOnColor); + rect->setReleasedColor(tempOffColor); + rect->setName(newName); + rect->setBrush(tempOffColor); // 应用关状态颜色 + } + selectedItem->update(); + } +} void MainWindow::createEllipse(const QPointF &pos) { ResizableEllipse *ellipse = new ResizableEllipse(pos.x(), pos.y(), 50, 50); @@ -305,9 +374,12 @@ void MainWindow::showContextMenu(QPoint pos) QAction* deleteAction = contextMenu.addAction("删除"); QAction* onAction = contextMenu.addAction("置为ON"); QAction* offAction = contextMenu.addAction("置为OFF"); + pasteAction->setEnabled(!copiedItemsData.isEmpty()); // 连接动作到现有功能 connect(deleteAction, &QAction::triggered, this, &MainWindow::onActionDeleteTriggered); connect(copyAction, &QAction::triggered, this, &MainWindow::onActionCopyTriggered); connect(pasteAction, &QAction::triggered, this, &MainWindow::onActionPasteTriggered); + connect(propertiesAction, &QAction::triggered, this, &MainWindow::onActionPropertiesTriggered); + contextMenu.exec(pos+QPoint(10, 10)); } diff --git a/IntegratedPlatform/mainwindow.h b/IntegratedPlatform/mainwindow.h index d68e16c..d294672 100644 --- a/IntegratedPlatform/mainwindow.h +++ b/IntegratedPlatform/mainwindow.h @@ -22,9 +22,10 @@ private slots: void onActionDeleteTriggered(); // 添加删除功能的槽函数 void onActionCopyTriggered();//复制功能槽函数 void onActionPasteTriggered();//粘贴功能槽函数 - void createEllipse(const QPointF &pos); // 创建指示灯(圆形) - void createRectangle(const QPointF &pos); // 创建按钮(矩形) - void resetDrawFlags(); // 重置绘制标志 + void onActionPropertiesTriggered();//属性页 + void createEllipse(const QPointF &pos);// 创建指示灯(圆形) + void createRectangle(const QPointF &pos);// 创建按钮(矩形) + void resetDrawFlags();// 重置绘制标志 void showContextMenu(QPoint pos); protected: bool eventFilter(QObject *obj, QEvent *event) override; diff --git a/untitled/document.cpp b/untitled/document.cpp new file mode 100644 index 0000000..3bbb386 --- /dev/null +++ b/untitled/document.cpp @@ -0,0 +1,408 @@ +#include "document.h" +#include "graphicsitems.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +HMIDocument::HMIDocument(QWidget *parent) + : BaseDocument(HMI, parent), + m_title("未命名HMI"), + m_canDrawEllipse(false), + m_canDrawRectangle(false), + m_lastPastePos(0, 0) +{ + // 创建绘图场景 + m_scene = new QGraphicsScene(this); + m_scene->setSceneRect(0, 0, 800, 600); + m_scene->setBackgroundBrush(QBrush(Qt::lightGray)); + + // 创建视图 + m_view = new QGraphicsView(m_scene, this); + m_view->setRenderHint(QPainter::Antialiasing); + m_view->setDragMode(QGraphicsView::RubberBandDrag); + m_view->setAcceptDrops(true); + m_view->viewport()->installEventFilter(this); + + // 布局(让视图占满文档区域) + auto layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_view); + setLayout(layout); +} + +HMIDocument::~HMIDocument() +{ +} + +// 事件过滤器(处理绘图、拖拽等事件) +bool HMIDocument::eventFilter(QObject *obj, QEvent *event) +{ + if (obj != m_view->viewport()) { + return QWidget::eventFilter(obj, event); + } + + // 鼠标按下事件(绘制图形) + if (event->type() == QEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + + if (mouseEvent->button() == Qt::RightButton) + { + // 右键菜单 + showContextMenu(mouseEvent->globalPos()); + return true; + } + if (mouseEvent->button() == Qt::LeftButton) + { + QPointF scenePos = m_view->mapToScene(mouseEvent->pos()); + QGraphicsItem *item = m_scene->itemAt(scenePos, m_view->transform()); + + // 如果点击空白区域且有绘制标志,创建图形 + if (!item) { + if (m_canDrawEllipse) { + createEllipse(scenePos); + resetDrawFlags(); + } else if (m_canDrawRectangle) { + createRectangle(scenePos); + resetDrawFlags(); + } + m_scene->clearSelection(); // 清除选择 + return true; + } + } + } + + // 拖拽事件(从工具栏拖拽绘制) + if (event->type() == QEvent::DragEnter) { + QDragEnterEvent *dragEvent = static_cast(event); + dragEvent->acceptProposedAction(); + return true; + } + if (event->type() == QEvent::DragMove) { + static_cast(event)->acceptProposedAction(); + return true; + } + if (event->type() == QEvent::Drop) { + QDropEvent *dropEvent = static_cast(event); + const QMimeData *mimeData = dropEvent->mimeData(); // 显式获取mimeData + QPointF scenePos = m_view->mapToScene(dropEvent->pos()); + + // 使用QMimeData + if (mimeData && mimeData->hasText()) { + QString type = mimeData->text(); + if (type == "指示灯") { + createEllipse(scenePos); + } else if (type == "按钮") { + createRectangle(scenePos); + } + } + dropEvent->acceptProposedAction(); + return true; + } + + return QWidget::eventFilter(obj, event); +} + +// 创建椭圆(指示灯) +void HMIDocument::createEllipse(const QPointF &pos) +{ + ResizableEllipse *ellipse = new ResizableEllipse(pos.x(), pos.y(), 50, 50); + ellipse->setBrush(QBrush(Qt::red)); + ellipse->setPen(QPen(Qt::black, 1)); + m_scene->addItem(ellipse); + ellipse->setSelected(true); +} + +// 创建矩形(按钮) +void HMIDocument::createRectangle(const QPointF &pos) +{ + ResizableRectangle *rect = new ResizableRectangle(pos.x(), pos.y(), 100, 50); + rect->setBrush(QBrush(Qt::yellow)); + rect->setPen(QPen(Qt::black, 1)); + m_scene->addItem(rect); + rect->setSelected(true); +} + +// 重置绘制标志 +void HMIDocument::resetDrawFlags() +{ + m_canDrawEllipse = false; + m_canDrawRectangle = false; +} + +// 右键菜单 +void HMIDocument::showContextMenu(QPoint globalPos) +{ + QPoint viewportPos = m_view->mapFromGlobal(globalPos); + QPointF scenePos = m_view->mapToScene(viewportPos); + QGraphicsItem *clickedItem = m_scene->itemAt(scenePos, m_view->transform()); + + QMenu menu(this); + + if (!clickedItem) { + // 空白区域:仅显示粘贴 + QAction *pasteAction = menu.addAction("粘贴"); + pasteAction->setEnabled(!m_copiedItemsData.isEmpty()); + connect(pasteAction, &QAction::triggered, this, &HMIDocument::pasteItems); + } else { + // 选中图形:显示完整菜单 + QAction *propAction = menu.addAction("属性"); + QAction *copyAction = menu.addAction("复制"); + QAction *pasteAction = menu.addAction("粘贴"); + QAction *deleteAction = menu.addAction("删除"); + QAction *onAction = menu.addAction("置为ON"); + QAction *offAction = menu.addAction("置为OFF"); + + pasteAction->setEnabled(!m_copiedItemsData.isEmpty()); + + connect(propAction, &QAction::triggered, this, &HMIDocument::showItemProperties); + connect(copyAction, &QAction::triggered, this, &HMIDocument::copySelectedItems); + connect(pasteAction, &QAction::triggered, this, &HMIDocument::pasteItems); + connect(deleteAction, &QAction::triggered, this, &HMIDocument::deleteSelectedItems); + + // ON/OFF动作(针对指示灯和按钮) + connect(onAction, &QAction::triggered, [=]() { + if (auto ellipse = dynamic_cast(clickedItem)) { + ellipse->setBrush(ellipse->onColor()); + } else if (auto rect = dynamic_cast(clickedItem)) { + rect->setBrush(rect->pressedColor()); + } + }); + connect(offAction, &QAction::triggered, [=]() { + if (auto ellipse = dynamic_cast(clickedItem)) { + ellipse->setBrush(ellipse->offColor()); + } else if (auto rect = dynamic_cast(clickedItem)) { + rect->setBrush(rect->releasedColor()); + } + }); + } + + menu.exec(globalPos + QPoint(10, 10)); +} + +// 复制选中项 +void HMIDocument::copySelectedItems() +{ + m_copiedItemsData.clear(); + QList selectedItems = m_scene->selectedItems(); + if (selectedItems.isEmpty()) return; + + foreach (QGraphicsItem *item, selectedItems) { + m_copiedItemsData.append(serializeItem(item)); + } + m_lastPastePos = selectedItems.first()->pos(); +} + +// 粘贴项 +void HMIDocument::pasteItems() +{ + if (m_copiedItemsData.isEmpty()) return; + + QPointF offset(20, 20); + m_lastPastePos += offset; + m_scene->clearSelection(); + + foreach (const QByteArray &itemData, m_copiedItemsData) { + QGraphicsItem *newItem = deserializeItem(itemData); + if (newItem) { + m_scene->addItem(newItem); + newItem->setPos(m_lastPastePos); + newItem->setSelected(true); + } + } +} + +// 删除选中项 +void HMIDocument::deleteSelectedItems() +{ + QList selectedItems = m_scene->selectedItems(); + foreach (QGraphicsItem *item, selectedItems) { + m_scene->removeItem(item); + delete item; + } +} + +// 显示属性对话框 +void HMIDocument::showItemProperties() +{ + QList selectedItems = m_scene->selectedItems(); + if (selectedItems.isEmpty()) return; + QGraphicsItem *item = selectedItems.first(); + + // 将QGraphicsItem转换为NamedItem + NamedItem *namedItem = dynamic_cast(item); + if (!namedItem) return; + + QDialog dialog(this); + dialog.setWindowTitle("属性设置"); + QFormLayout *form = new QFormLayout(&dialog); + + // 名称输入 - 使用NamedItem接口 + QLineEdit *nameEdit = new QLineEdit(namedItem->name()); + + // 颜色选择(根据图形类型) + QColor tempColor1, tempColor2; + QPushButton *colorBtn1 = new QPushButton; + QPushButton *colorBtn2 = new QPushButton; + + if (auto ellipse = dynamic_cast(item)) { + tempColor1 = ellipse->onColor(); + tempColor2 = ellipse->offColor(); + form->addRow("ON颜色:", colorBtn1); + form->addRow("OFF颜色:", colorBtn2); + } else if (auto rect = dynamic_cast(item)) { + tempColor1 = rect->pressedColor(); + tempColor2 = rect->releasedColor(); + form->addRow("按下颜色:", colorBtn1); + form->addRow("释放颜色:", colorBtn2); + } + + // 初始化颜色按钮 + colorBtn1->setStyleSheet("background-color:" + tempColor1.name()); + colorBtn2->setStyleSheet("background-color:" + tempColor2.name()); + + // 颜色选择对话框 + connect(colorBtn1, &QPushButton::clicked, [&]() { + QColor c = QColorDialog::getColor(tempColor1, &dialog); + if (c.isValid()) { + tempColor1 = c; + colorBtn1->setStyleSheet("background-color:" + c.name()); + } + }); + connect(colorBtn2, &QPushButton::clicked, [&]() { + QColor c = QColorDialog::getColor(tempColor2, &dialog); + if (c.isValid()) { + tempColor2 = c; + colorBtn2->setStyleSheet("background-color:" + c.name()); + } + }); + + // 布局组装 + form->addRow("名称:", nameEdit); + QDialogButtonBox *btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + form->addRow(btnBox); + connect(btnBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + connect(btnBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + // 应用属性 + if (dialog.exec() == QDialog::Accepted) { + // 使用NamedItem接口设置名称 + namedItem->setName(nameEdit->text()); + + if (auto ellipse = dynamic_cast(item)) { + ellipse->setOnColor(tempColor1); + ellipse->setOffColor(tempColor2); + } else if (auto rect = dynamic_cast(item)) { + rect->setPressedColor(tempColor1); + rect->setReleasedColor(tempColor2); + } + item->update(); + } +} + +// 序列化图形项(用于复制粘贴) +QByteArray HMIDocument::serializeItem(QGraphicsItem *item) +{ + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + + // 基础信息 + stream << item->type(); + stream << item->pos(); + stream << item->flags(); + stream << item->transform(); + stream << item->isVisible(); + + // 形状信息 + if (auto shape = dynamic_cast(item)) { + stream << shape->pen(); + stream << shape->brush(); + stream << shape->boundingRect(); + } + + // 具体图形信息 + if (auto rect = dynamic_cast(item)) { + stream << rect->rect(); + stream << rect->pressedColor(); + stream << rect->releasedColor(); + stream << rect->name(); + } else if (auto ellipse = dynamic_cast(item)) { + stream << ellipse->rect(); + stream << ellipse->onColor(); + stream << ellipse->offColor(); + stream << ellipse->name(); + } + + return data; +} + +// 反序列化图形项(用于粘贴) +QGraphicsItem *HMIDocument::deserializeItem(const QByteArray &data) +{ + QDataStream stream(data); + int type; + QPointF pos; + QGraphicsItem::GraphicsItemFlags flags; + QTransform transform; + bool visible; + + stream >> type >> pos >> flags >> transform >> visible; + + QGraphicsItem *item = nullptr; + if (type == QGraphicsRectItem::Type) { + QPen pen; + QBrush brush; + QRectF boundRect; + QRectF rect; + QColor pressedColor, releasedColor; + QString name; + + stream >> pen >> brush >> boundRect >> rect >> pressedColor >> releasedColor >> name; + + ResizableRectangle *rectItem = new ResizableRectangle(0, 0, rect.width(), rect.height()); + rectItem->setPen(pen); + rectItem->setBrush(brush); + rectItem->setPressedColor(pressedColor); + rectItem->setReleasedColor(releasedColor); + rectItem->setName(name); + item = rectItem; + } else if (type == QGraphicsEllipseItem::Type) { + QPen pen; + QBrush brush; + QRectF boundRect; + QRectF rect; + QColor onColor, offColor; + QString name; + + stream >> pen >> brush >> boundRect >> rect >> onColor >> offColor >> name; + + ResizableEllipse *ellipseItem = new ResizableEllipse(0, 0, rect.width(), rect.height()); + ellipseItem->setPen(pen); + ellipseItem->setBrush(brush); + ellipseItem->setOnColor(onColor); + ellipseItem->setOffColor(offColor); + ellipseItem->setName(name); + item = ellipseItem; + } + + if (item) { + item->setFlags(flags); + item->setTransform(transform); + item->setVisible(visible); + } + + return item; +} diff --git a/untitled/document.h b/untitled/document.h new file mode 100644 index 0000000..8c0a012 --- /dev/null +++ b/untitled/document.h @@ -0,0 +1,92 @@ +#ifndef DOCUMENT_H +#define DOCUMENT_H + +#include +#include +#include +#include +#include +#include + +// 前向声明 +class ResizableRectangle; +class ResizableEllipse; +class NamedItem; + +// 文档基类 +class BaseDocument : public QWidget +{ + Q_OBJECT +public: + enum DocumentType { HMI, PLC }; + BaseDocument(DocumentType type, QWidget *parent = nullptr) + : QWidget(parent), m_type(type) {} + virtual ~BaseDocument() = default; + DocumentType type() const { return m_type; } + virtual QString title() const = 0; + +protected: + DocumentType m_type; +}; + +// HMI文档类(包含绘图相关核心功能) +class HMIDocument : public BaseDocument +{ + Q_OBJECT +public: + HMIDocument(QWidget *parent = nullptr); + ~HMIDocument() override; + + QString title() const override { return m_title; } + void setTitle(const QString &title) { m_title = title; } + QGraphicsView *view() const { return m_view; } + QGraphicsScene *scene() const { return m_scene; } + + // 绘图控制 + void setDrawEllipse(bool enable) { m_canDrawEllipse = enable; } + void setDrawRectangle(bool enable) { m_canDrawRectangle = enable; } + + // 编辑功能 + void copySelectedItems(); + void pasteItems(); + void deleteSelectedItems(); + void showItemProperties(); + +signals: + void titleChanged(const QString &title); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +private: + // 绘图相关 + void createEllipse(const QPointF &pos); + void createRectangle(const QPointF &pos); + void resetDrawFlags(); + void showContextMenu(QPoint globalPos); + + // 图形项序列化/反序列化 + QByteArray serializeItem(QGraphicsItem *item); + QGraphicsItem *deserializeItem(const QByteArray &data); + + QString m_title; + QGraphicsScene *m_scene; + QGraphicsView *m_view; + bool m_canDrawEllipse; + bool m_canDrawRectangle; + + // 复制粘贴相关 + QList m_copiedItemsData; + QPointF m_lastPastePos; +}; + +// PLC文档类(预留,暂为空实现) +class PLCDocument : public BaseDocument +{ + Q_OBJECT +public: + PLCDocument(QWidget *parent = nullptr) : BaseDocument(PLC, parent) {} + QString title() const override { return "PLC文档"; } +}; + +#endif // DOCUMENT_H diff --git a/untitled/graphicsitems.cpp b/untitled/graphicsitems.cpp new file mode 100644 index 0000000..28f7e29 --- /dev/null +++ b/untitled/graphicsitems.cpp @@ -0,0 +1,26 @@ +#include "graphicsitems.h" +#include + +// 可调整大小的矩形(按钮)实现 +ResizableRectangle::ResizableRectangle(qreal x, qreal y, qreal w, qreal h) + : ResizableShape(x, y, w, h) +{ + m_name = "按钮"; + m_pressedColor = Qt::green; + m_releasedColor = Qt::yellow; + this->setBrush(m_releasedColor); +} + +// 可调整大小的椭圆(指示灯)实现 +ResizableEllipse::ResizableEllipse(qreal x, qreal y, qreal w, qreal h) + : ResizableShape(x, y, w, h) +{ + m_name = "指示灯"; + m_onColor = Qt::green; + m_offColor = Qt::red; + this->setBrush(m_onColor); +} + +// 显式实例化模板类 +template class ResizableShape; +template class ResizableShape; diff --git a/untitled/graphicsitems.h b/untitled/graphicsitems.h new file mode 100644 index 0000000..6e5fd61 --- /dev/null +++ b/untitled/graphicsitems.h @@ -0,0 +1,143 @@ +#ifndef GRAPHICSITEMS_H +#define GRAPHICSITEMS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 命名项接口(用于属性设置) +class NamedItem +{ +public: + virtual QString name() const = 0; + virtual void setName(const QString &name) = 0; + virtual ~NamedItem() = default; +}; + +// 可调整大小的图形基类(模板) +template +class ResizableShape : public BaseShape, public NamedItem +{ +protected: + bool m_resizing; + QString m_name; + Qt::CursorShape m_currentCursor; + +public: + ResizableShape(qreal x, qreal y, qreal w, qreal h) + : BaseShape(x, y, w, h), m_resizing(false), m_currentCursor(Qt::SizeAllCursor) + { + this->setFlag(QGraphicsItem::ItemIsMovable, true); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + this->setAcceptHoverEvents(true); + } + + // 事件处理(调整大小逻辑) + void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override + { + if (isInResizeArea(event->pos())) { + m_currentCursor = Qt::SizeFDiagCursor; + } else { + m_currentCursor = Qt::SizeAllCursor; + } + BaseShape::hoverMoveEvent(event); + } + + void mousePressEvent(QGraphicsSceneMouseEvent *event) override + { + if (isInResizeArea(event->pos())) { + m_resizing = true; + m_currentCursor = Qt::SizeFDiagCursor; + } else { + m_resizing = false; + m_currentCursor = Qt::SizeAllCursor; + BaseShape::mousePressEvent(event); + } + } + + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override + { + if (m_resizing) { + QRectF newRect = this->rect(); + newRect.setBottomRight(event->pos()); + this->setRect(newRect); + } else { + BaseShape::mouseMoveEvent(event); + } + } + + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override + { + m_resizing = false; + m_currentCursor = Qt::SizeAllCursor; + BaseShape::mouseReleaseEvent(event); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override + { + BaseShape::paint(painter, option, widget); + } + + // 命名项接口实现 + QString name() const override { return m_name; } + void setName(const QString &name) override { m_name = name; } + + // 光标获取方法 + Qt::CursorShape currentCursor() const { return m_currentCursor; } + +protected: + bool isInResizeArea(const QPointF &pos) const + { + QRectF r = this->rect(); + QRectF resizeArea(r.bottomRight() - QPointF(20, 20), r.bottomRight()); + return resizeArea.contains(pos); + } +}; + +// 可调整大小的矩形(按钮) +class ResizableRectangle : public ResizableShape +{ +public: + ResizableRectangle(qreal x, qreal y, qreal w, qreal h); + + QColor pressedColor() const { return m_pressedColor; } + void setPressedColor(const QColor &color) { m_pressedColor = color; } + + QColor releasedColor() const { return m_releasedColor; } + void setReleasedColor(const QColor &color) { + m_releasedColor = color; + this->setBrush(m_releasedColor); // 更新显示 + } + +private: + QColor m_pressedColor; // 按下颜色 + QColor m_releasedColor; // 释放颜色 +}; + +// 可调整大小的椭圆(指示灯) +class ResizableEllipse : public ResizableShape +{ +public: + ResizableEllipse(qreal x, qreal y, qreal w, qreal h); + + QColor onColor() const { return m_onColor; } + void setOnColor(const QColor &color) { + m_onColor = color; + this->setBrush(m_onColor); // 更新显示 + } + + QColor offColor() const { return m_offColor; } + void setOffColor(const QColor &color) { m_offColor = color; } + +private: + QColor m_onColor; // 开状态颜色 + QColor m_offColor; // 关状态颜色 +}; + +#endif // GRAPHICSITEMS_H diff --git a/untitled/hmieditor.cpp b/untitled/hmieditor.cpp new file mode 100644 index 0000000..abee2c5 --- /dev/null +++ b/untitled/hmieditor.cpp @@ -0,0 +1,73 @@ +#include "hmieditor.h" +#include +#include + +void Shape::draw(QPainter& painter) const { + painter.setPen(QPen(Qt::blue, 2)); + painter.setBrush(QBrush(Qt::lightGray, Qt::DiagCrossPattern)); + + if (type == Circle) { + painter.drawEllipse(rect); + } else if (type == Rectangle) { + painter.drawRect(rect); + } +} +HMIEditor::HMIEditor(QWidget *parent) + : QWidget(parent), currentShapeType(Shape::Rectangle), isDrawing(false) +{ + setMinimumSize(400, 300); + setStyleSheet("background-color: white;"); +} + +void HMIEditor::onDrawCircle() { + currentShapeType = Shape::Circle; +} + +void HMIEditor::onDrawRect() { + currentShapeType = Shape::Rectangle; +} + +void HMIEditor::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QPainter painter(this); + + // 绘制所有已完成的图形 + for (const auto& shape : shapes) { + shape.draw(painter); + } + + // 绘制正在绘制的图形 + if (isDrawing) { + painter.setPen(QPen(Qt::red, 2, Qt::DashLine)); + if (currentShapeType == Shape::Circle) { + painter.drawEllipse(currentDrawingRect); + } else { + painter.drawRect(currentDrawingRect); + } + } +} + +void HMIEditor::mousePressEvent(QMouseEvent *event) { + if (event->button() == Qt::LeftButton) { + isDrawing = true; + currentDrawingRect.setTopLeft(event->pos()); + currentDrawingRect.setBottomRight(event->pos()); + update(); + } +} + +void HMIEditor::mouseReleaseEvent(QMouseEvent *event) { + if (event->button() == Qt::LeftButton && isDrawing) { + isDrawing = false; + currentDrawingRect.setBottomRight(event->pos()); + shapes.emplace_back(currentShapeType, currentDrawingRect); + update(); + } +} + +void HMIEditor::mouseMoveEvent(QMouseEvent *event) { + if (isDrawing) { + currentDrawingRect.setBottomRight(event->pos()); + update(); + } +} diff --git a/untitled/hmieditor.h b/untitled/hmieditor.h new file mode 100644 index 0000000..34a9589 --- /dev/null +++ b/untitled/hmieditor.h @@ -0,0 +1,45 @@ +#ifndef HMIEDITOR_H +#define HMIEDITOR_H + +#include +#include +#include +#include + +// 图形元素基类 +class Shape { +public: + enum Type { Circle, Rectangle }; + + Shape(Type type, const QRect& rect) : type(type), rect(rect) {} + virtual void draw(QPainter& painter) const; + + Type type; + QRect rect; +}; + +class HMIEditor : public QWidget +{ + Q_OBJECT + +public: + explicit HMIEditor(QWidget *parent = nullptr); + +public slots: + void onDrawCircle(); + void onDrawRect(); + +protected: + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + +private: + std::vector shapes; + Shape::Type currentShapeType; + bool isDrawing; + QRect currentDrawingRect; +}; + +#endif // HMIEDITOR_H diff --git a/untitled/images/T-常开触点-01.png b/untitled/images/T-常开触点-01.png new file mode 100644 index 0000000..91b4566 Binary files /dev/null and b/untitled/images/T-常开触点-01.png differ diff --git a/untitled/images/T-常闭触点-01-01.png b/untitled/images/T-常闭触点-01-01.png new file mode 100644 index 0000000..6a2a0f5 Binary files /dev/null and b/untitled/images/T-常闭触点-01-01.png differ diff --git a/untitled/images/大于等于.png b/untitled/images/大于等于.png new file mode 100644 index 0000000..2aba72f Binary files /dev/null and b/untitled/images/大于等于.png differ diff --git a/untitled/images/按钮.png b/untitled/images/按钮.png new file mode 100644 index 0000000..3df91d9 Binary files /dev/null and b/untitled/images/按钮.png differ diff --git a/untitled/images/灯泡.png b/untitled/images/灯泡.png new file mode 100644 index 0000000..2030e66 Binary files /dev/null and b/untitled/images/灯泡.png differ diff --git a/untitled/images/线-圈-圈.png b/untitled/images/线-圈-圈.png new file mode 100644 index 0000000..0962b1b Binary files /dev/null and b/untitled/images/线-圈-圈.png differ diff --git a/untitled/main.cpp b/untitled/main.cpp new file mode 100644 index 0000000..b0f00a2 --- /dev/null +++ b/untitled/main.cpp @@ -0,0 +1,15 @@ +#include "mainwindow.h" +#include +#include +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + // 设置应用程序信息 + a.setApplicationName("综合平台编程器"); + QApplication::setStyle(QStyleFactory::create("Fusion")); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/untitled/mainwindow.cpp b/untitled/mainwindow.cpp new file mode 100644 index 0000000..d37a4b6 --- /dev/null +++ b/untitled/mainwindow.cpp @@ -0,0 +1,215 @@ +#include "mainwindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + setWindowTitle("综合平台编程器"); + setGeometry(100, 100, 1000, 700); + + // 初始化标签页 + m_tabWidget = new QTabWidget(this); + m_tabWidget->setTabsClosable(true); + setCentralWidget(m_tabWidget); + connect(m_tabWidget, &QTabWidget::currentChanged, this, &MainWindow::onTabChanged); + + // 创建菜单和工具栏 + createMenus(); + createToolbars(); +} + +MainWindow::~MainWindow() +{ + // 标签页和工具栏由Qt自动销毁 +} + +// 创建菜单栏 +// 在createMenus()函数中添加以下代码,用于创建操作菜单及其功能 + +void MainWindow::createMenus() +{ + // 创建文件菜单(保持原有代码) + QMenu *fileMenu = menuBar()->addMenu("文件"); + QMenu *editMenu = menuBar()->addMenu("操作"); + QMenu *simulationMenu = menuBar()->addMenu("仿真"); + + // 新建HMI动作(保持原有代码) + QAction *newHmiAction = new QAction("新建HMI(&H)", this); + newHmiAction->setShortcut(tr("Ctrl+H")); + newHmiAction->setStatusTip("创建新的HMI文档"); + connect(newHmiAction, &QAction::triggered, this, &MainWindow::onNewHMI); + fileMenu->addAction(newHmiAction); + + // 新建PLC动作(保持原有代码) + QAction *newPlcAction = new QAction("新建PLC(&P)", this); + newPlcAction->setShortcut(tr("Ctrl+P")); + newPlcAction->setStatusTip("创建新的PLC文档"); + connect(newPlcAction, &QAction::triggered, this, &MainWindow::onNewPLC); + fileMenu->addAction(newPlcAction); + + // 操作菜单 - 添加复制、粘贴、删除功能 + QAction *copyAction = new QAction("复制(&C)", this); + copyAction->setShortcut(QKeySequence::Copy); // 标准复制快捷键 Ctrl+C + copyAction->setStatusTip("复制选中的项目"); + connect(copyAction, &QAction::triggered, this, [this]() { + // 获取当前活动的HMI文档 + if (auto hmiDoc = dynamic_cast(m_tabWidget->currentWidget())) { + hmiDoc->copySelectedItems(); + } + }); + + QAction *pasteAction = new QAction("粘贴(&V)", this); + pasteAction->setShortcut(QKeySequence::Paste); // 标准粘贴快捷键 Ctrl+V + pasteAction->setStatusTip("粘贴复制的项目"); + connect(pasteAction, &QAction::triggered, this, [this]() { + if (auto hmiDoc = dynamic_cast(m_tabWidget->currentWidget())) { + hmiDoc->pasteItems(); + } + }); + + QAction *deleteAction = new QAction("删除(&D)", this); + deleteAction->setShortcut(QKeySequence::Delete); // 删除键 + deleteAction->setStatusTip("删除选中的项目"); + connect(deleteAction, &QAction::triggered, this, [this]() { + if (auto hmiDoc = dynamic_cast(m_tabWidget->currentWidget())) { + hmiDoc->deleteSelectedItems(); + } + }); + + // 添加到操作菜单 + editMenu->addAction(copyAction); + editMenu->addAction(pasteAction); + editMenu->addAction(deleteAction); +} + + +// 创建左侧工具栏 +void MainWindow::createToolbars() +{ + m_leftToolBar = new QToolBar("绘图工具", this); + addToolBar(Qt::LeftToolBarArea, m_leftToolBar); + m_leftToolBar->setAllowedAreas(Qt::LeftToolBarArea); // 仅允许在左侧 +} + +// 更新工具栏(根据当前文档类型) +void MainWindow::updateToolBar(BaseDocument *doc) +{ + // 清空现有工具 + m_leftToolBar->clear(); + + if (!doc) return; + + // HMI文档显示绘图工具 + if (doc->type() == BaseDocument::HMI) + { + HMIDocument *hmiDoc = dynamic_cast(doc); + if (!hmiDoc) return; + + // 画指示灯按钮(支持拖拽) + QToolButton *ellipseBtn = new QToolButton; + ellipseBtn->setText("指示灯"); + ellipseBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + ellipseBtn->setIcon(QIcon("../two/untitled/images/灯泡.png")); // 可替换为实际图标 + ellipseBtn->setMinimumSize(120, 120); + connect(ellipseBtn, &QToolButton::clicked, [=]() { + hmiDoc->setDrawEllipse(true); + hmiDoc->setDrawRectangle(false); + }); + + // 为按钮安装事件过滤器处理拖拽 + ellipseBtn->installEventFilter(this); + ellipseBtn->setProperty("toolType", "指示灯"); + m_leftToolBar->addWidget(ellipseBtn); + + // 画按钮按钮(支持拖拽) + QToolButton *rectBtn = new QToolButton; + rectBtn->setText("按钮"); + rectBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + rectBtn->setIcon(QIcon("../two/untitled/images/按钮.png")); // 可替换为实际图标 + rectBtn->setMinimumSize(120, 120); + connect(rectBtn, &QToolButton::clicked, [=]() { + hmiDoc->setDrawRectangle(true); + hmiDoc->setDrawEllipse(false); + }); + + // 为按钮安装事件过滤器处理拖拽 + rectBtn->installEventFilter(this); + rectBtn->setProperty("toolType", "按钮"); + m_leftToolBar->addWidget(rectBtn); + } + + // PLC文档可添加自己的工具 + else if (doc->type() == BaseDocument::PLC) { + m_leftToolBar->addAction("常开触点"); + m_leftToolBar->addAction("常闭触点"); + } +} + +// 事件过滤器处理拖拽 +bool MainWindow::eventFilter(QObject *obj, QEvent *event) +{ + // 检查是否是工具栏按钮的鼠标按下事件 + QToolButton *toolBtn = qobject_cast(obj); + if (toolBtn && event->type() == QEvent::MouseButtonPress) + { + QMouseEvent *me = static_cast(event); + if (me->button() == Qt::LeftButton) + { + // 获取工具类型 + QString toolType = toolBtn->property("toolType").toString(); + if (!toolType.isEmpty()) + { + // 创建拖拽 + QMimeData *mime = new QMimeData; + mime->setText(toolType); + QDrag *drag = new QDrag(obj); + drag->setMimeData(mime); + drag->exec(Qt::CopyAction); + return true; + } + } + } + return QMainWindow::eventFilter(obj, event); +} + +// 新建HMI文档 +void MainWindow::onNewHMI() +{ + m_hmiCount++; + HMIDocument *doc = new HMIDocument; + doc->setTitle(QString("HMI文档 %1").arg(m_hmiCount)); + m_tabWidget->addTab(doc, doc->title()); + m_tabWidget->setCurrentWidget(doc); + updateToolBar(doc); // 更新工具栏为HMI工具 +} + +// 新建PLC文档 +void MainWindow::onNewPLC() +{ + m_plcCount++; + PLCDocument *doc = new PLCDocument; + m_tabWidget->addTab(doc, QString("PLC文档 %1").arg(m_plcCount)); + m_tabWidget->setCurrentWidget(doc); + updateToolBar(doc); // 更新工具栏为PLC工具 +} + +// 标签页切换时更新工具栏 +void MainWindow::onTabChanged(int idx) +{ + if (idx < 0) { + updateToolBar(nullptr); + return; + } + BaseDocument *doc = dynamic_cast(m_tabWidget->widget(idx)); + updateToolBar(doc); +} diff --git a/untitled/mainwindow.h b/untitled/mainwindow.h new file mode 100644 index 0000000..2ecc0d3 --- /dev/null +++ b/untitled/mainwindow.h @@ -0,0 +1,40 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include "document.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +private slots: + void onNewHMI(); // 新建HMI文档 + void onNewPLC(); // 新建PLC文档 + void onTabChanged(int idx); // 标签页切换时更新工具栏 + +private: + void createMenus(); // 创建菜单栏 + void createToolbars(); // 创建工具栏(左侧) + void updateToolBar(BaseDocument *doc); // 根据文档类型更新工具栏 + + QTabWidget *m_tabWidget; // 多文档标签页 + QToolBar *m_leftToolBar; // 左侧工具栏 + int m_hmiCount = 0; // HMI文档计数器 + int m_plcCount = 0; // PLC文档计数器 +}; + +#endif // MAINWINDOW_H diff --git a/untitled/mainwindow.ui b/untitled/mainwindow.ui new file mode 100644 index 0000000..b232854 --- /dev/null +++ b/untitled/mainwindow.ui @@ -0,0 +1,22 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + + + diff --git a/untitled/plceditor.cpp b/untitled/plceditor.cpp new file mode 100644 index 0000000..466ade8 --- /dev/null +++ b/untitled/plceditor.cpp @@ -0,0 +1,72 @@ +#include "plceditor.h" +#include +#include +#include + +PLCElement::PLCElement(Type type, QGraphicsItem *parent) + : QGraphicsRectItem(parent), type(type) +{ + setRect(0, 0, 60, 30); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); +} + +void PLCElement::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + Q_UNUSED(option); + Q_UNUSED(widget); + + // 绘制基本形状 + painter->setPen(QPen(Qt::black, 2)); + painter->setBrush(QBrush(Qt::white)); + painter->drawRect(rect()); + + // 绘制触点类型 + painter->setPen(QPen(Qt::red, 2)); + if (type == NormallyOpen) { + // 常开触点 + painter->drawLine(10, 15, 25, 15); + painter->drawLine(35, 15, 50, 15); + painter->drawLine(25, 10, 35, 20); + } else { + // 常闭触点 + painter->drawLine(10, 15, 25, 15); + painter->drawLine(35, 15, 50, 15); + painter->drawLine(25, 20, 35, 10); + painter->drawLine(25, 10, 35, 20); + } +} + +PLCEditor::PLCEditor(QWidget *parent) + : QWidget(parent), elementCount(0) +{ + // 创建布局 + QVBoxLayout* layout = new QVBoxLayout(this); + + // 创建图形场景和视图 + scene = new QGraphicsScene(this); + scene->setSceneRect(0, 0, 800, 600); + scene->setBackgroundBrush(Qt::lightGray); + + view = new QGraphicsView(scene, this); + view->setRenderHint(QPainter::Antialiasing); + layout->addWidget(view); +} + +void PLCEditor::onNormallyOpen() { + // 创建新的常开触点 + PLCElement* element = new PLCElement(PLCElement::NormallyOpen); + scene->addItem(element); + + // 放置在不同位置 + element->setPos(50 + (elementCount % 10) * 80, 50 + (elementCount / 10) * 50); + elementCount++; +} + +void PLCEditor::onNormallyClosed() { + // 创建新的常闭触点 + PLCElement* element = new PLCElement(PLCElement::NormallyClosed); + scene->addItem(element); + + // 放置在不同位置 + element->setPos(50 + (elementCount % 10) * 80, 50 + (elementCount / 10) * 50); + elementCount++; +} diff --git a/untitled/plceditor.h b/untitled/plceditor.h new file mode 100644 index 0000000..592e2f1 --- /dev/null +++ b/untitled/plceditor.h @@ -0,0 +1,40 @@ +#ifndef PLCEDITOR_H +#define PLCEDITOR_H + +#include +#include +#include +#include +#include +#include + +class PLCElement : public QGraphicsRectItem { +public: + enum Type { NormallyOpen, NormallyClosed }; + + PLCElement(Type type, QGraphicsItem *parent = nullptr); + Type getType() const { return type; } + +private: + Type type; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; +}; + +class PLCEditor : public QWidget +{ + Q_OBJECT + +public: + explicit PLCEditor(QWidget *parent = nullptr); + +public slots: + void onNormallyOpen(); + void onNormallyClosed(); + +private: + QGraphicsScene* scene; + QGraphicsView* view; + int elementCount; +}; + +#endif // PLCEDITOR_H diff --git a/untitled/untitled.pro b/untitled/untitled.pro new file mode 100644 index 0000000..af0ada3 --- /dev/null +++ b/untitled/untitled.pro @@ -0,0 +1,35 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + document.cpp \ + graphicsitems.cpp \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + document.h \ + graphicsitems.h \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/untitled/untitled.pro.user b/untitled/untitled.pro.user new file mode 100644 index 0000000..563ea85 --- /dev/null +++ b/untitled/untitled.pro.user @@ -0,0 +1,563 @@ + + + + + + EnvironmentId + {a9bf9b5a-270d-4be3-80ad-6036193da221} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + untitled2 + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/admin/Desktop/two/untitled/untitled.pro + C:/Users/admin/Desktop/two/untitled/untitled.pro + + false + + false + true + true + false + false + true + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + C:/Users/admin/Desktop/build-untitled-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + +