#include "hmieditorwidget.h" #include "hmiwidgetfactory.h" #include #include #include #include #include #include #include #include #include #include #include #include "hmicontrolitem.h" HmiEditorWidget::HmiEditorWidget(QWidget* parent) : QWidget(parent) { QHBoxLayout* mainLayout = new QHBoxLayout(this); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(10); QVBoxLayout* leftLayout = new QVBoxLayout(); leftLayout->setSpacing(5); hmiToolbar = new QListWidget(this); hmiToolbar->setViewMode(QListWidget::IconMode); hmiToolbar->setIconSize(QSize(48, 48)); hmiToolbar->setFixedWidth(100); hmiToolbar->setSpacing(10); hmiToolbar->setDragEnabled(false); QListWidgetItem* buttonItem = new QListWidgetItem(); buttonItem->setIcon(QIcon(":resource/image/button.png")); buttonItem->setData(Qt::UserRole, QString("按钮")); buttonItem->setToolTip("按钮"); hmiToolbar->addItem(buttonItem); QListWidgetItem* ledItem = new QListWidgetItem(); ledItem->setIcon(QIcon(":resource/image/light.png")); ledItem->setData(Qt::UserRole, QString("指示灯")); ledItem->setToolTip("指示灯"); hmiToolbar->addItem(ledItem); leftLayout->addWidget(hmiToolbar); m_newPageButton = new QPushButton("新建页面", this); m_deletePageButton = new QPushButton("删除页面", this); m_prevPageButton = new QPushButton("上一页", this); m_nextPageButton = new QPushButton("下一页", this); m_pageLabel = new QLabel("无页面", this); leftLayout->addWidget(m_newPageButton); leftLayout->addWidget(m_deletePageButton); leftLayout->addWidget(m_prevPageButton); leftLayout->addWidget(m_nextPageButton); leftLayout->addWidget(m_pageLabel); leftLayout->addStretch(); mainLayout->addLayout(leftLayout); hmiEditArea = new QGraphicsView(this); hmiEditArea->setRenderHint(QPainter::Antialiasing); hmiEditArea->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); hmiEditArea->setOptimizationFlags(QGraphicsView::DontSavePainterState | QGraphicsView::DontAdjustForAntialiasing); hmiEditArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); hmiEditArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); mainLayout->addWidget(hmiEditArea, 1); hmiEditArea->installEventFilter(this); connect(hmiToolbar, &QListWidget::itemClicked, this, &HmiEditorWidget::onToolbarItemClicked); connect(m_newPageButton, &QPushButton::clicked, this, &HmiEditorWidget::onNewPageClicked); connect(m_deletePageButton, &QPushButton::clicked, this, &HmiEditorWidget::onDeletePageClicked); connect(m_prevPageButton, &QPushButton::clicked, this, &HmiEditorWidget::onPreviousPageClicked); connect(m_nextPageButton, &QPushButton::clicked, this, &HmiEditorWidget::onNextPageClicked); ensureViewReady(); } HmiEditorWidget::~HmiEditorWidget() { clearPages(); } void HmiEditorWidget::ensureViewReady() { QCoreApplication::processEvents(); hmiEditArea->resetTransform(); hmiEditArea->viewport()->update(); if (hmiEditArea->viewport()->rect().isEmpty()) { hmiEditArea->setFixedSize(600, 400); QCoreApplication::processEvents(); } } void HmiEditorWidget::showEvent(QShowEvent* event) { QWidget::showEvent(event); if (m_firstShow && m_pages.isEmpty()) { m_firstShow = false; createNewPage(); } } void HmiEditorWidget::createNewPage() { QGraphicsScene* newScene = new QGraphicsScene(this); QRect viewRect = hmiEditArea->viewport()->rect(); if (viewRect.isEmpty()) { viewRect = QRect(0, 0, 800, 600); hmiEditArea->setSceneRect(viewRect); } newScene->setSceneRect(viewRect); m_pages.append(newScene); m_currentPageIndex = m_pages.size() - 1; QMetaObject::invokeMethod(this, [this, newScene]() { hmiEditArea->setScene(newScene); initViewScale(); updatePageLabel(); hmiEditArea->viewport()->update(); }, Qt::QueuedConnection); } void HmiEditorWidget::refreshView() { if (m_currentPageIndex >= 0 && !m_pages.isEmpty()) { hmiEditArea->setScene(nullptr); hmiEditArea->setScene(m_pages[m_currentPageIndex]); initViewScale(); hmiEditArea->viewport()->update(); } } void HmiEditorWidget::initViewScale() { if (!hmiEditArea || m_currentPageIndex < 0 || m_pages.isEmpty()) { return; } QRect viewRect = hmiEditArea->viewport()->rect(); if (viewRect.isEmpty()) { viewRect = QRect(0, 0, 800, 600); } QGraphicsScene* currentScene = m_pages[m_currentPageIndex]; currentScene->setSceneRect(viewRect); hmiEditArea->fitInView(viewRect, Qt::KeepAspectRatio); hmiEditArea->viewport()->update(); } void HmiEditorWidget::updatePageLabel() { if (m_pages.isEmpty()) { m_pageLabel->setText("无页面"); m_deletePageButton->setEnabled(false); m_prevPageButton->setEnabled(false); m_nextPageButton->setEnabled(false); } else { m_pageLabel->setText(QString("第 %1/%2 页").arg(m_currentPageIndex + 1).arg(m_pages.size())); m_deletePageButton->setEnabled(m_pages.size() > 1); m_prevPageButton->setEnabled(m_currentPageIndex > 0); m_nextPageButton->setEnabled(m_currentPageIndex < m_pages.size() - 1); } } void HmiEditorWidget::switchToPage(int index) { if (index >= 0 && index < m_pages.size()) { m_currentPageIndex = index; hmiEditArea->resetTransform(); hmiEditArea->setScene(m_pages[index]); QRectF sceneRect = m_pages[index]->sceneRect(); if (!sceneRect.isEmpty()) { hmiEditArea->fitInView(sceneRect, Qt::KeepAspectRatio); } updatePageLabel(); QMetaObject::invokeMethod(this, [this]() { hmiEditArea->viewport()->update(); }, Qt::QueuedConnection); } } bool HmiEditorWidget::eventFilter(QObject* obj, QEvent* event) { if (obj == hmiEditArea && event->type() == QEvent::ContextMenu) { QContextMenuEvent* contextEvent = static_cast(event); if (m_currentPageIndex >= 0 && m_pages[m_currentPageIndex]) { QGraphicsItem* item = hmiEditArea->itemAt(contextEvent->pos()); if (!item) { QMenu menu; QAction* pasteAction = new QAction("粘贴", &menu); pasteAction->setEnabled(HmiControlItem::hasClipboardData()); QObject::connect(pasteAction, &QAction::triggered, [this, contextEvent]() { if (m_currentPageIndex >= 0 && m_pages[m_currentPageIndex] && HmiControlItem::hasClipboardData()) { QPointF scenePos = hmiEditArea->mapToScene(contextEvent->pos()); HmiControlItem* newItem = HmiControlItem::createFromClipboard(HmiControlItem::getClipboardData(), scenePos); if (newItem) { m_pages[m_currentPageIndex]->addItem(newItem); m_pages[m_currentPageIndex]->clearSelection(); newItem->setSelected(true); hmiEditArea->viewport()->update(); } } }); menu.addAction(pasteAction); menu.exec(contextEvent->globalPos()); } } return true; } return QWidget::eventFilter(obj, event); } void HmiEditorWidget::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); if (m_currentPageIndex >= 0 && !m_pages.isEmpty()) { initViewScale(); } } void HmiEditorWidget::keyPressEvent(QKeyEvent* event) { if (event->matches(QKeySequence::Copy)) { if (m_currentPageIndex >= 0 && m_pages[m_currentPageIndex]) { auto selectedItems = m_pages[m_currentPageIndex]->selectedItems(); if (!selectedItems.isEmpty()) { HmiControlItem* item = dynamic_cast(selectedItems.first()); if (item) { HmiControlItem::copyToClipboard(item->saveToClipboard()); } } } } else if (event->matches(QKeySequence::Paste)) { if (m_currentPageIndex >= 0 && m_pages[m_currentPageIndex] && HmiControlItem::hasClipboardData()) { QRectF sceneRect = m_pages[m_currentPageIndex]->sceneRect(); QPointF centerPos(sceneRect.width() / 2, sceneRect.height() / 2); HmiControlItem* newItem = HmiControlItem::createFromClipboard(HmiControlItem::getClipboardData(), centerPos); if (newItem) { m_pages[m_currentPageIndex]->addItem(newItem); m_pages[m_currentPageIndex]->clearSelection(); newItem->setSelected(true); hmiEditArea->viewport()->update(); } } } else if (event->matches(QKeySequence::Delete)) { if (m_currentPageIndex >= 0 && m_pages[m_currentPageIndex]) { auto selectedItems = m_pages[m_currentPageIndex]->selectedItems(); for (QGraphicsItem* item : selectedItems) { HmiControlItem* controlItem = dynamic_cast(item); if (controlItem) { controlItem->deleteItem(); } } hmiEditArea->viewport()->update(); } } QWidget::keyPressEvent(event); } void HmiEditorWidget::onToolbarItemClicked(QListWidgetItem* item) { if (!item || m_currentPageIndex < 0 || !m_pages[m_currentPageIndex]) return; QString type = item->data(Qt::UserRole).toString(); HmiControlItem* newItem = nullptr; if (type == "按钮") { newItem = new HmiButton(); } else if (type == "指示灯") { newItem = new HmiLed(); } if (newItem) { QRectF sceneRect = m_pages[m_currentPageIndex]->sceneRect(); newItem->setPos(sceneRect.width() / 2, sceneRect.height() / 2); m_pages[m_currentPageIndex]->addItem(newItem); m_pages[m_currentPageIndex]->clearSelection(); newItem->setSelected(true); hmiEditArea->viewport()->update(); } } void HmiEditorWidget::onNewPageClicked() { createNewPage(); } void HmiEditorWidget::onDeletePageClicked() { if (m_currentPageIndex >= 0 && m_pages.size() > 1) { QGraphicsScene* scene = m_pages[m_currentPageIndex]; m_pages.removeAt(m_currentPageIndex); delete scene; m_currentPageIndex = qMin(m_currentPageIndex, m_pages.size() - 1); hmiEditArea->setScene(m_pages[m_currentPageIndex]); initViewScale(); updatePageLabel(); hmiEditArea->viewport()->update(); } } void HmiEditorWidget::onPreviousPageClicked() { switchToPage(m_currentPageIndex - 1); } void HmiEditorWidget::onNextPageClicked() { switchToPage(m_currentPageIndex + 1); } void HmiEditorWidget::clearPages() { for (QGraphicsScene* scene : m_pages) { delete scene; } m_pages.clear(); m_currentPageIndex = -1; hmiEditArea->setScene(nullptr); updatePageLabel(); }