393 lines
11 KiB
C++
393 lines
11 KiB
C++
#pragma once
|
|
#include <QApplication>
|
|
#include <QWidget>
|
|
#include <QVBoxLayout>
|
|
#include <QLabel>
|
|
#include <QGraphicsView>
|
|
#include <QGraphicsScene>
|
|
#include <QGraphicsPixmapItem>
|
|
#include <QPixmap>
|
|
#include <QWheelEvent>
|
|
#include <QKeyEvent>
|
|
#include <opencv.hpp>
|
|
#include <QMenu>
|
|
#include <QAction>
|
|
#include <qmessagebox.h>
|
|
#include <qmutex.h>
|
|
#include <uiModule/components/fancyButton.h>
|
|
#include "qscrollbar.h"
|
|
#include "globalStruct.h"
|
|
#include <qqueue.h>
|
|
#include <qthread.h>
|
|
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);
|
|
scene = new QGraphicsScene();
|
|
this->setScene(scene);
|
|
imgLabel = new QLabel();
|
|
scene->clear();
|
|
scene->addWidget(imgLabel);
|
|
imgLabel->setMaximumSize(9999, 9999);
|
|
this->setObjectName("SonGraphicsView");
|
|
this->setStyleSheet("QGraphicsView#SonGraphicsView {"
|
|
"background: transparent;"
|
|
"background-image: url(:/topBar/icon/waitting.png);"
|
|
"background-repeat: no-repeat;"
|
|
"background-position: center center;"
|
|
"}");
|
|
mutex.unlock();
|
|
}
|
|
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<float>(imageWidth) / FOVImage.width();
|
|
float scaleY = static_cast<float>(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();
|
|
setEnabled(true);
|
|
setMouseTracking(true);
|
|
QRect rect = img.rect();
|
|
imageWidth = rect.width();
|
|
imageHeight = rect.height();
|
|
|
|
imgLabel->setFixedSize(imageWidth, imageHeight);
|
|
imgLabel->setPixmap(img);
|
|
setSceneRect(rect);
|
|
this->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 {
|
|
Q_OBJECT
|
|
public:
|
|
fancyButton* switchBtn;
|
|
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);
|
|
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);
|
|
}
|
|
public slots:
|
|
//set不一定显示,要根据当前显示的类型决定
|
|
void setOriImg(QPixmap oriImgInput)
|
|
{
|
|
pixOriImg = oriImgInput;
|
|
if (pixOriImg.isNull()) {
|
|
return;
|
|
}
|
|
if (MatType == false)
|
|
showImgOnGraphicsView(pixOriImg);
|
|
}
|
|
//set不一定显示,要根据当前显示的类型决定
|
|
void setResImg(QPixmap resImgInput)
|
|
{
|
|
pixResImg = resImgInput;
|
|
if (pixResImg.isNull()) {
|
|
return;
|
|
}
|
|
if (MatType == true)
|
|
showImgOnGraphicsView(pixResImg);
|
|
}
|
|
//无视当前类型直接显示
|
|
void showImgOnGraphicsView(QPixmap imageMat) {
|
|
view->setImg(imageMat);
|
|
}
|
|
void switchOriAndRes()//切换原图和结果图
|
|
{
|
|
if (MatType == false)
|
|
{
|
|
if(!pixResImg.isNull())
|
|
showImgOnGraphicsView(pixResImg);
|
|
label2->setText(u8"结果图");
|
|
}
|
|
else
|
|
{
|
|
if (!pixOriImg.isNull())
|
|
showImgOnGraphicsView(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();
|
|
}
|
|
}
|
|
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_map<QString, ImageWidget*>map;
|
|
void disableAllSwitchBtn()
|
|
{
|
|
for (auto widget : ImageWidgetList)
|
|
widget->switchBtn->hide();
|
|
}
|
|
|
|
bool showImg(QPixmap img, imgWidgetShowType _type, int index)
|
|
{
|
|
if (index > ImageWidgetList.size())
|
|
return false;
|
|
switch (_type)
|
|
{
|
|
case imgWidgetOri:
|
|
ImageWidgetList[index]->setOriImg(img);
|
|
return true;
|
|
break;
|
|
case imgWidgetRes:
|
|
ImageWidgetList[index]->setResImg(img);
|
|
return true;
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}; |