#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qscrollbar.h" #include "globalStruct.h" #include #include class ImageWidgetManager; class SonGraphicsView : public QGraphicsView { //Q_OBJECT public: QGraphicsScene* scene; SonGraphicsView() { //scene = new QGraphicsScene(); //this->setScene(scene); mutex.lock(); setDragMode(QGraphicsView::DragMode::NoDrag); setInteractive(false); setEnabled(false); this->setStyleSheet("QGraphicsView {" "background: transparent;" "background-image: url(:/topBar/icon/waitting.png);" "background-repeat: no-repeat;" "background-position: center center;" "background-size: contain;" "}"); //initShow(); scene = new QGraphicsScene(this); this->setScene(scene); //this->fitInView(pixmapItem, Qt::KeepAspectRatio); this->setBackgroundBrush(QBrush(QColor(0, 0, 0))); setEnabled(true); setMouseTracking(true); imgLabel = new QLabel(); scene->clear(); scene->addWidget(imgLabel); imgLabel->setMaximumSize(9999, 9999); mutex.unlock(); } void setImg(QImage& image) { if (image.isNull()) return; showimg(QPixmap::fromImage(image)); } void setImg(cv::Mat& src) { if (src.empty()) return; showimg(QPixmap::fromImage(cvMatToQImage(src))); } void setImg(QPixmap& pixmap) { showimg(pixmap); } void resetImage() { scene->clear(); setEnabled(false); } protected: virtual void wheelEvent(QWheelEvent* event) override { if (scene->children().size()==0) return; QPoint numDegrees = event->angleDelta() / 8; if (!numDegrees.isNull()) { QPoint numSteps = numDegrees / 15; zoom(numSteps); } event->accept(); } virtual void keyPressEvent(QKeyEvent* event) override { //if (event->key() == Qt::Key_O) { // this->resetTransform(); // this->setSceneRect(m_image.rect()); // this->fitInView(QRect(0, 0, m_image.width(), m_image.height()), Qt::KeepAspectRatio); //} } virtual void mousePressEvent(QMouseEvent* event) override { if (event->button() == Qt::LeftButton) { togglePan(true, event->pos()); event->accept(); return; } event->ignore(); } virtual void mouseMoveEvent(QMouseEvent* event) override { if (m_isPan) { pan(event->pos()); event->accept(); return; } event->ignore(); } virtual void mouseReleaseEvent(QMouseEvent* event) override { if (event->button() == Qt::LeftButton) { togglePan(false); event->accept(); return; } event->ignore(); } void zoom(QPoint factor) { QRectF FOV = this->mapToScene(this->rect()).boundingRect(); QRectF FOVImage = QRectF(FOV.left(), FOV.top(), FOV.width(), FOV.height()); float scaleX = static_cast(imageWidth) / FOVImage.width(); float scaleY = static_cast(imageHeight) / FOVImage.height(); float minScale = scaleX > scaleY ? scaleY : scaleX; float maxScale = scaleX > scaleY ? scaleX : scaleY; if ((factor.y() > 0 && minScale > 100) || (factor.y() < 0 && maxScale < 1)) { return; } if (factor.y() > 0) scale(1.2, 1.2); else scale(0.8, 0.8); } void togglePan(bool pan, const QPoint& startPos = QPoint()) { if (pan) { if (m_isPan) { return; } m_isPan = true; m_prevPan = startPos; setCursor(Qt::ClosedHandCursor); } else { if (!m_isPan) { return; } m_isPan = false; m_prevPan = QPoint(0, 0); setCursor(Qt::ArrowCursor); } } void pan(const QPoint& panTo) { auto hBar = horizontalScrollBar(); auto vBar = verticalScrollBar(); auto delta = panTo - m_prevPan; m_prevPan = panTo; hBar->setValue(hBar->value() - delta.x()); vBar->setValue(vBar->value() - delta.y()); } private: void showimg(QPixmap& img) { mutex.lock(); //scene->clear(); //scene->addPixmap(img); imgLabel->setPixmap(img); QRect rect = img.rect(); imageWidth = rect.width(); imageHeight = rect.height(); imgLabel->setFixedSize(imageWidth, imageHeight); setSceneRect(rect); fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); mutex.unlock(); } bool m_isPan; QPoint m_prevPan; QLabel* imgLabel; QGraphicsItemGroup* rectGroup = nullptr; int imageWidth = 1; int imageHeight = 1; QMutex mutex; }; class ImageWidget : public QWidget { public: ImageWidget(QWidget* parent = nullptr) : QWidget(parent) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(5, 5, 5, 5); view = new SonGraphicsView(); this->setMaximumSize(9999, 9999); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); QFont font("微软雅黑", 12, QFont::Bold); QHBoxLayout* hLayout = new QHBoxLayout(); label = new QLabel(u8"相机1"); label->setAlignment(Qt::AlignLeft); label->setFont(font); label->setPalette(palette); label2 = new QLabel(u8"原图"); label2->setAlignment(Qt::AlignLeft); label2->setFont(font); label2->setPalette(palette); hLayout->addWidget(label); hLayout->addWidget(label2); hLayout->setContentsMargins(0, 0, 0, 0); fancyButton* switchBtn = new fancyButton( 30, 30, QIcon(":/topBar/icon/switch.png"), "切换结果图与原图" ); connect(switchBtn, &QPushButton::clicked, [=]() { switchOriAndRes(); }); hLayout->addWidget(switchBtn); layout->addLayout(hLayout); layout->addWidget(view); view->setDragMode(QGraphicsView::ScrollHandDrag); view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); view->setRenderHint(QPainter::Antialiasing); view->setRenderHint(QPainter::SmoothPixmapTransform); view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //item = new QGraphicsPixmapItem(); //scene->addItem(item); //view->fitInView(item, Qt::KeepAspectRatio); //view->setBackgroundBrush(QBrush(QColor(0, 0, 0))); //QPixmap backgroundImage(".//icon//watting.png"); // 替换为你的背景图片路径 //QGraphicsPixmapItem* backgroundItem = new QGraphicsPixmapItem(backgroundImage); //view->scene->addItem(backgroundItem); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QWidget::customContextMenuRequested, this, &ImageWidget::showContextMenu); } void setTitle(const QString& text) { label->setText(text); } //set不一定显示,要根据当前显示的类型决定 void setOriImg(cv::Mat& oriImgInput) { if (oriImgInput.empty()) { return; } pixOriImg = QPixmap::fromImage(cvMatToQImage(oriImgInput).rgbSwapped()); if (pixOriImg.isNull()) { return; } oriImg= oriImgInput; if (MatType == false) showImg(pixOriImg); } //set不一定显示,要根据当前显示的类型决定 void setResImg(cv::Mat& resImgInput) { if (resImgInput.empty()) { return; } pixResImg = QPixmap::fromImage(cvMatToQImage(resImgInput).rgbSwapped()); if (pixResImg.isNull()) { return; } resImg = resImgInput; if (MatType == true) showImg(pixResImg); } //set不一定显示,要根据当前显示的类型决定 void setOriImg(QPixmap& oriImgInput) { pixOriImg = oriImgInput; if (pixOriImg.isNull()) { return; } if (MatType == false) showImg(pixOriImg); } //set不一定显示,要根据当前显示的类型决定 void setResImg(QPixmap& resImgInput) { pixResImg = resImgInput; if (pixResImg.isNull()) { return; } if (MatType == true) showImg(pixResImg); } //无视当前类型直接显示 void showImg(cv::Mat& imageMat) { if (imageMat.empty()) { return; } QImage img(imageMat.data, imageMat.cols, imageMat.rows, imageMat.step, QImage::Format_RGB888); if (img.isNull()) { return; } QPixmap pixmap = QPixmap::fromImage(img.rgbSwapped()); if (pixmap.isNull()) { return; } view->setImg(pixmap); } void showImg(QPixmap& imageMat) { view->setImg(imageMat); } void switchOriAndRes()//切换原图和结果图 { if (MatType == false) { if(pixOriImg.isNull()) showImg(resImg); else showImg(pixResImg); label2->setText(u8"结果图"); } else { if (pixOriImg.isNull()) showImg(oriImg); else showImg(pixOriImg); label2->setText(u8"原图"); } MatType = !MatType; } protected: void wheelEvent(QWheelEvent* event) override { if (event->modifiers() & Qt::ControlModifier) { double scaleFactor = 1.15; if (event->angleDelta().y() < 0) { scaleFactor = 1.0 / scaleFactor; } view->scale(scaleFactor, scaleFactor); event->accept(); } else { QWidget::wheelEvent(event); } } private: void paintEvent(QPaintEvent* event) override { QWidget::paintEvent(event); QPainter painter(this); painter.setPen(QPen(Qt::white, 1)); painter.drawRect(rect().adjusted(1, 1, -2, -2)); } void showContextMenu(const QPoint& pos) { QMenu contextMenu(tr("Context Menu"), this); QAction* action1 = new QAction(u8"切换原图/结果图", this); contextMenu.addAction(action1); QAction* selectedAction = contextMenu.exec(mapToGlobal(pos)); if (selectedAction == action1) { switchOriAndRes(); } } cv::Mat oriImg; cv::Mat resImg; QPixmap pixOriImg; QPixmap pixResImg; bool MatType = false;//false ori true Res int in = 0; QLabel* label; QLabel* label2; //SonGraphicsView* scene; //QGraphicsPixmapItem* item; SonGraphicsView* view; }; class ImageWidgetManager :public QWidget { public: QGridLayout* Layout = new QGridLayout(); ImageWidgetManager() { this->setLayout(Layout); Layout->setContentsMargins(0, 0, 0, 0); } ~ImageWidgetManager() { } ImageWidget* createViewer(QString nickName = "none") { ImageWidget* ImageView = new ImageWidget(); ImageWidgetList.push_back(ImageView); if (nickName != "none") map.insert({ nickName,ImageView }); ImageView->setTitle(nickName); Layout->addWidget(ImageView); return ImageView; } QMutex mutex; QList< ImageWidget*>ImageWidgetList; std::unordered_mapmap; bool showImg(cv::Mat& img, imgWidgetShowType _type , int index) { if (index > ImageWidgetList.size()) return false; switch (_type) { case imgWidgetOri: ImageWidgetList[index]->setOriImg(img); break; case imgWidgetRes: ImageWidgetList[index]->setResImg(img); break; } } bool showImg(cv::Mat& img, imgWidgetShowType _type, QString nickName) { if (map.find(nickName) == map.end()) return false; switch (_type) { case imgWidgetOri: map[nickName]->setOriImg(img); break; case imgWidgetRes: map[nickName]->setResImg(img); break; } } bool showImg(QPixmap& img, imgWidgetShowType _type, int index) { if (index > ImageWidgetList.size()) return false; switch (_type) { case imgWidgetOri: ImageWidgetList[index]->setOriImg(img); break; case imgWidgetRes: ImageWidgetList[index]->setResImg(img); break; } } bool showImg(QPixmap& img, imgWidgetShowType _type, QString nickName) { if (map.find(nickName) == map.end()) return false; switch (_type) { case imgWidgetOri: map[nickName]->setOriImg(img); break; case imgWidgetRes: map[nickName]->setResImg(img); break; } } };