#include "WaferGraphicsView.h" #include #include WaferGraphicsView::WaferGraphicsView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent), selecting(false), selectionRect(nullptr), m_scene(scene), scaleFactor(1.0), isDragging(false), thumbnailLabel(nullptr), thumbnailVisible(false) { setRenderHint(QPainter::Antialiasing); // setDragMode(QGraphicsView::ScrollHandDrag); // 支持拖动视图 setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // 缩放时以鼠标为中心 // 初始化缩略图标签 thumbnailLabel = new QLabel(this); thumbnailLabel->setFixedSize(150, 150); thumbnailLabel->move(0, 0); // 默认左上角位置 thumbnailLabel->setStyleSheet("background-color: white; border: 1px solid gray;"); thumbnailLabel->installEventFilter(this); thumbnailLabel->hide(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); setScene(m_scene); // 禁用并隐藏水平滚动条 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBar(nullptr); // 禁用并隐藏垂直滚动条 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBar(nullptr); setDragMode(QGraphicsView::NoDrag); } // 事件过滤器用于处理缩略图拖动 bool WaferGraphicsView::eventFilter(QObject* obj, QEvent* event) { static QPoint dragStartPosition; if (obj == thumbnailLabel) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent* me = static_cast(event); dragStartPosition = me->pos(); return true; } else if (event->type() == QEvent::MouseMove) { QMouseEvent* me = static_cast(event); // 计算新位置 QPoint newPos = thumbnailLabel->pos() + (me->pos() - dragStartPosition); // 限制在视图范围内 int maxX = this->width() - thumbnailLabel->width(); int maxY = this->height() - thumbnailLabel->height(); // 使用qBound限制坐标范围(0 <= x <= maxX,0 <= y <= maxY) newPos.setX(qBound(0, newPos.x(), maxX)); newPos.setY(qBound(0, newPos.y(), maxY)); thumbnailLabel->move(newPos); return true; } } return QGraphicsView::eventFilter(obj, event); } void WaferGraphicsView::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { // 清空选中的 DieItem for (auto& item : selectedItemsMap) { DieItem* die = dynamic_cast(item); if (die) { die->setSelected(false); // 取消选中状态 } } selectedItemsMap.clear(); if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); // 获取点击位置的 DieItem if (selectedItem && selectedItem->scene()) { selectedItem->setLeftSelected(false); } selectedItem.clear(); QGraphicsItem* item = itemAt(event->pos()); if (item) { selectedItem = dynamic_cast(item); selectedItem->setLeftSelected(true); } setCursor(Qt::OpenHandCursor); // 按下时设置为小手 selecting = true; lastPos = event->pos(); // 记录鼠标位置 } else if (event->button() == Qt::RightButton) { // 开始框选 selecting = true; selectionStart = mapToScene(event->pos()); isDragging = false; if (!selectionRect) { selectionRect = new QGraphicsRectItem(); selectionRect->setPen(QPen(Qt::NoPen)); selectionRect->setBrush(QBrush(QColor(0, 0, 255, 50))); // 半透明蓝色 scene()->addItem(selectionRect); } selectionRect->setRect(QRectF(selectionStart, QSizeF())); } QGraphicsView::mousePressEvent(event); } void WaferGraphicsView::mouseMoveEvent(QMouseEvent* event) { if (selecting && selectionRect) { QPointF currentPos = mapToScene(event->pos()); selectionRect->setRect(QRectF(selectionStart, currentPos).normalized()); isDragging = true; } else if (selecting) { // 计算鼠标当前位置与上次位置的差值 QPointF delta = event->pos() - lastPos; // 平移视图 horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x()); verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y()); lastPos = event->pos(); // 更新鼠标位置 } QGraphicsView::mouseMoveEvent(event); } void WaferGraphicsView::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { setCursor(Qt::ArrowCursor); // 松开时恢复为箭头 selecting = false; } else if (event->button() == Qt::RightButton && selecting) { selecting = false; if (selectionRect && isDragging) { if (selectedItem && selectedItem->scene()) { selectedItem->setLeftSelected(false); } selectedItem.clear(); if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); QRectF selectedArea = selectionRect->rect(); scene()->removeItem(selectionRect); delete selectionRect; selectionRect = nullptr; QList items = scene()->items(selectedArea, Qt::IntersectsItemShape); for (QGraphicsItem* item : items) { DieItem* die = dynamic_cast(item); if (die) { // 将 DieItem 添加到 map 中 selectedItemsMap.insert(qMakePair(die->getRow(), die->getCol()), die); die->setSelected(true); // 设置选中状态 } } } if (selectionRect) { scene()->removeItem(selectionRect); delete selectionRect; selectionRect = nullptr; } // 如果没有进行拖动,则弹出右键菜单 if (!isDragging) { QGraphicsItem* item = itemAt(event->pos()); DieItem* die = dynamic_cast(item); QMenu menu; QAction* showThumb = menu.addAction(thumbnailVisible ? tr("Hide thumbnails", "隐藏缩略图") : tr("Show thumbnails", "显示缩略图")); connect(showThumb, &QAction::triggered, [this] { thumbnailVisible ? hideThumbnail() : showThumbnail(); }); menu.addAction(tr("Send Location", "发送位置"), [this] { if (selectedItem) { qDebug() << "Row:" << selectedItem->getRow() << "Col:" << selectedItem->getCol(); selectedItem->setLeftSelected(false); selectedItem = nullptr; } }); if (die) { menu.addAction(tr("move to current location","移动到该位置"), [this, die] { for (auto& item : selectedItemsMap) { DieItem* die = dynamic_cast(item); if (die) { die->setSelected(false); } } selectedItemsMap.clear(); if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); if (selectedItem && selectedItem->scene()) { selectedItem->setLeftSelected(false); } selectedItem.clear(); selectedItem = die; selectedItem->setLeftSelected(true); }); // 设置区域边界点菜单 menu.addAction(tr("set Top left point","设为左上点"), [this, die] { if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); topLeftItem = die; topLeftItem->setRightSelected(true); topLeftIndex = qMakePair(die->getRow(), die->getCol()); if (bottomRightIndex.first >= 0) checkAndCreateRegion(); }); menu.addAction(tr("set bottom right point","设为右下点"), [this, die] { if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); bottomRightItem = die; bottomRightItem->setRightSelected(true); bottomRightIndex = qMakePair(die->getRow(), die->getCol()); if (topLeftIndex.first >= 0) checkAndCreateRegion(); }); } menu.addAction(tr("clear the selected area","清除选中区域"), [this] { clearRegion(); }); menu.addAction(tr("set area","设置区域"), [this] { setRegion(); }); menu.exec(event->globalPos()); } } QGraphicsView::mouseReleaseEvent(event); } void WaferGraphicsView::wheelEvent(QWheelEvent* event) { if (event->orientation() == Qt::Vertical) { event->ignore(); // 忽略竖直滚轮事件(即禁用滚动条滑动) return; } event->accept(); } // 缩略图功能实现 void WaferGraphicsView::showThumbnail() { // 本地图片路径(根据实际路径修改) QString imagePath = ":/images/test_image/image_1.png"; // 替换为本地图片路径 // 加载本地图片 QPixmap thumb(imagePath); if (!thumb.isNull()) { // 如果图片加载成功,设置为缩略图 thumbnailLabel->setPixmap(thumb.scaled(150, 150, Qt::KeepAspectRatio)); thumbnailLabel->show(); thumbnailVisible = true; } else { // 如果加载图片失败,显示"图片加载失败" thumbnailLabel->setText("图片加载失败"); thumbnailLabel->setAlignment(Qt::AlignCenter); // 居中显示文本 thumbnailLabel->show(); thumbnailVisible = true; } } void WaferGraphicsView::hideThumbnail() { thumbnailLabel->hide(); thumbnailVisible = false; thumbnailLabel->move(0, 0); } void WaferGraphicsView::checkAndCreateRegion() { // 仅当两个点都有效时处理 if (topLeftIndex.first < 0 || bottomRightIndex.first < 0) return; // 确定行列范围 int startRow = qMin(topLeftIndex.first, bottomRightIndex.first); int endRow = qMax(topLeftIndex.first, bottomRightIndex.first); int startCol = qMin(topLeftIndex.second, bottomRightIndex.second); int endCol = qMax(topLeftIndex.second, bottomRightIndex.second); // 遍历场景中的所有项 foreach(QGraphicsItem * item, scene()->items()) { if (DieItem* die = dynamic_cast(item)) { int row = die->getRow(); int col = die->getCol(); // 判断是否在区域内 if (row >= startRow && row <= endRow && col >= startCol && col <= endCol) { // 更新选中状态 die->setSelected(true); selectedItemsMap.insert(qMakePair(row, col), die); } } } // 重置索引点 topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); } void WaferGraphicsView::clearRegion() { // 清空选中的 DieItem for (auto& item : selectedItemsMap) { DieItem* die = dynamic_cast(item); if (die) { die->setSelected(false); // 取消选中状态 } } selectedItemsMap.clear(); if (selectedItem && selectedItem->scene()) { selectedItem->setLeftSelected(false); } selectedItem.clear(); if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); // 清除缩略图 hideThumbnail(); } void WaferGraphicsView::setRegion() { for (auto it = selectedItemsMap.begin(); it != selectedItemsMap.end(); ++it) { QPair key = it.key(); // 获取当前元素的 key qDebug() << "Row:" << key.first << ", Col:" << key.second; } // 清空选中的 DieItem for (auto& item : selectedItemsMap) { DieItem* die = dynamic_cast(item); if (die) { die->setSelected(false); // 取消选中状态 } } selectedItemsMap.clear(); if (selectedItem && selectedItem->scene()) { selectedItem->setLeftSelected(false); } selectedItem.clear(); if (topLeftItem && topLeftItem->scene()) { topLeftItem->setRightSelected(false); } topLeftItem.clear(); if (bottomRightItem && bottomRightItem->scene()) { bottomRightItem->setRightSelected(false); } bottomRightItem.clear(); topLeftIndex = qMakePair(-1, -1); bottomRightIndex = qMakePair(-1, -1); } void WaferGraphicsView::initWafer(const QPointF& center, double radius, int dieWidth, int dieHeight,double angle) { m_center = center; m_radius = radius; m_dieSize = QSize(dieWidth, dieHeight); // 清空场景 m_scene->clear(); qDebug() << "Center:" << m_center << "Radius:" << m_radius; // 绘制晶圆外圆 QGraphicsEllipseItem* waferCircle = new QGraphicsEllipseItem( m_center.x() - radius, m_center.y() - radius, (radius) * 2, (radius) * 2 ); waferCircle->setPen(QPen(Qt::blue, 2)); m_scene->addItem(waferCircle); double x, y; if (angle == 0.0) { x = m_center.x(); y = m_center.y() + radius -5; } else if (angle == 90.0) { x = m_center.x() - radius; y = m_center.y(); } else if (angle == 180.0) { x = m_center.x(); y = m_center.y() - radius; } else if (angle == 270.0) { x = m_center.x() + radius -5; y = m_center.y(); } QGraphicsRectItem* rect = m_scene->addRect(x, y, 5, 5, QPen(Qt::black, 0.5),QBrush(Qt::black)); } void WaferGraphicsView::addDiePoint(const QPointF& diePos,const WAFER_MATRIX_POINT_INFO_STRUCT& dieInfo) { // 创建图形项 DieItem* dieItem = new DieItem(dieInfo); //QPointF diePosUpdate(diePos.x() + dieInfo.nDieRow * m_dieSize.width(), diePos.y() + dieInfo.nDieCol * m_dieSize.height()); dieItem->setRect( diePos.x() - m_dieSize.width() / 2, diePos.y() - m_dieSize.height() / 2, m_dieSize.width(), m_dieSize.height() ); // 存储映射关系 m_dieItems.insert(dieInfo.iDieIndex, dieItem); m_scene->addItem(dieItem); } void WaferGraphicsView::drawDieMatrix(const QPointF& center, int Width, int Height, int DieMatrixId) { QGraphicsRectItem* rect = m_scene->addRect(center.x(), center.y(), Width, Height, QPen(Qt::blue, 0.5)); QGraphicsTextItem* text = new QGraphicsTextItem(QString(tr("DieMatrix%1")).arg(DieMatrixId)); text->setPos(center.x(), center.y()); QFont font = text->font(); // 获取当前字体 font.setPointSize(6); // 设置字体大小为 8,可以根据需要调整 text->setFont(font); // 应用新的字体 m_scene->addItem(text); }