备份 更新整理后的稳定版本
This commit is contained in:
@@ -0,0 +1,461 @@
|
||||
#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 "global.h"
|
||||
#include <qqueue.h>
|
||||
#include <qthread.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qmutex.h>
|
||||
#include <qmap.h>
|
||||
#include <qbuffer.h>
|
||||
#include <qimagewriter.h>
|
||||
#include <qgraphicsproxywidget.h>
|
||||
class ImageWidgetManager;
|
||||
//单画幅
|
||||
class SonGraphicsView :
|
||||
public QGraphicsView
|
||||
{
|
||||
//Q_OBJECT
|
||||
public:
|
||||
QString name;
|
||||
QGraphicsScene* scene;
|
||||
SonGraphicsView(QString nameIn):
|
||||
name (nameIn)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
setDragMode(QGraphicsView::DragMode::NoDrag);
|
||||
setInteractive(false);
|
||||
setEnabled(false);
|
||||
|
||||
scene = new QGraphicsScene();
|
||||
this->setScene(scene);
|
||||
scene->clear();
|
||||
this->setObjectName("SonGraphicsView");
|
||||
this->setStyleSheet("QGraphicsView#SonGraphicsView {"
|
||||
"background: transparent;"
|
||||
"background-image: url(:/icon/icon/waitting.png);"
|
||||
"background-repeat: no-repeat;"
|
||||
"background-position: center center;"
|
||||
"}");
|
||||
rectGroup = new QGraphicsItemGroup();
|
||||
scene->addItem(rectGroup);
|
||||
}
|
||||
void setImg(QPixmap pixmap)
|
||||
{
|
||||
showImg(pixmap);
|
||||
}
|
||||
void resetImage()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
scene->clear();
|
||||
setEnabled(false);
|
||||
}
|
||||
protected:
|
||||
void deleteAllRect()
|
||||
{
|
||||
if (rectGroup == nullptr)
|
||||
return;
|
||||
QList<QGraphicsItem*> items = rectGroup->childItems();
|
||||
for (QGraphicsItem* item : items) {
|
||||
QGraphicsRectItem* rect = qgraphicsitem_cast<QGraphicsRectItem*>(item);
|
||||
rectGroup->removeFromGroup(rect);
|
||||
scene->removeItem(rect);
|
||||
delete rect;
|
||||
}
|
||||
}
|
||||
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);
|
||||
centerOn(currentPos);
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (event->button() == Qt::RightButton) {
|
||||
startPos = mapToScene(event->pos());
|
||||
rightClicked = true;
|
||||
rectItem = new QGraphicsRectItem(QRectF(startPos, QSizeF(0, 0)));
|
||||
rectItem->setPen(QPen(Qt::red, 10));
|
||||
rectGroup->addToGroup(rectItem);
|
||||
this->update();
|
||||
return;
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) override
|
||||
{
|
||||
currentPos = mapToScene(event->pos());
|
||||
if (rightClicked == true)
|
||||
{
|
||||
QPointF endPos = currentPos;
|
||||
// 计算矩形的宽度和高度
|
||||
qreal width = endPos.x() - startPos.x();
|
||||
qreal height = endPos.y() - startPos.y();26;
|
||||
rectItem->setTransformOriginPoint(startPos);
|
||||
rectItem->setRect(startPos.x(), startPos.y(), width, height);
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (event->button() == Qt::RightButton) {
|
||||
rightClicked = false;
|
||||
deleteAllRect();
|
||||
QPointF endPos = mapToScene(event->pos());
|
||||
// 计算矩形的宽度和高度
|
||||
qreal width = endPos.x() - startPos.x();
|
||||
qreal height = endPos.y() - startPos.y(); 26;
|
||||
auto rect = this->rect();
|
||||
double scaleRate = std::max(rect.width() / width, rect.height() / height);
|
||||
scale(scaleRate, scaleRate);
|
||||
centerOn(startPos.x() + width / 2, startPos.y() + height / 2);
|
||||
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:
|
||||
bool rightClicked = false;
|
||||
QPointF currentPos;
|
||||
QPointF startPos;
|
||||
QGraphicsItemGroup* rectGroup;
|
||||
QGraphicsRectItem* rectItem;
|
||||
void showImg(QPixmap img)
|
||||
{
|
||||
try {
|
||||
QMutexLocker locker(&mutex);
|
||||
setEnabled(true);
|
||||
setMouseTracking(true);
|
||||
QRect rect = img.rect();
|
||||
imageWidth = rect.width();
|
||||
imageHeight = rect.height();
|
||||
{
|
||||
if (imgLabel != nullptr) {
|
||||
// 从 scene 移除
|
||||
QList<QGraphicsItem*> items = scene->items();
|
||||
for (QGraphicsItem* item : items) {
|
||||
QGraphicsProxyWidget* proxy = qgraphicsitem_cast<QGraphicsProxyWidget*>(item);
|
||||
if (proxy && proxy->widget() == imgLabel) {
|
||||
scene->removeItem(proxy);
|
||||
delete proxy; // 这会自动删除 imgLabel
|
||||
break;
|
||||
}
|
||||
}
|
||||
imgLabel = nullptr;
|
||||
}
|
||||
imgLabel = new QLabel();
|
||||
scene->addWidget(imgLabel);
|
||||
imgLabel->setMaximumSize(9999, 9999);
|
||||
}
|
||||
|
||||
imgLabel->setFixedSize(imageWidth, imageHeight);
|
||||
imgLabel->setPixmap(img);
|
||||
setSceneRect(rect);
|
||||
this->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
catch (...) {
|
||||
qDebug() << "showImg error";
|
||||
}
|
||||
}
|
||||
bool m_isPan;
|
||||
QPoint m_prevPan;
|
||||
QLabel* imgLabel = nullptr;
|
||||
int imageWidth = 1; int imageHeight = 1;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
//切换窗口 在切换时用pixmap替换现有的以实现
|
||||
class ImageWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
fancyButton* switchBtn;
|
||||
QComboBox switchBox;
|
||||
QMutex switchBoxMutex;
|
||||
ImageWidget(QWidget* parent = nullptr) : QWidget(parent) {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(5, 5, 5, 5);
|
||||
viewer = 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);
|
||||
|
||||
switchBox.setFont(font);
|
||||
switchBox.setPalette(palette);
|
||||
connect(&switchBox, &QComboBox::currentTextChanged, [=](QString type)
|
||||
{
|
||||
switchViewType(type);
|
||||
});
|
||||
|
||||
|
||||
hLayout->addWidget(label);
|
||||
hLayout->addWidget(&switchBox);
|
||||
hLayout->setContentsMargins(0, 0, 0, 0);
|
||||
switchBtn = new fancyButton(
|
||||
30,
|
||||
30,
|
||||
QIcon(":/icon/icon/switch.png"),
|
||||
"切换结果图与原图"
|
||||
);
|
||||
hLayout->addWidget(switchBtn);
|
||||
|
||||
layout->addLayout(hLayout);
|
||||
layout->addWidget(viewer);
|
||||
|
||||
viewer->setDragMode(QGraphicsView::ScrollHandDrag);
|
||||
viewer->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
viewer->setRenderHint(QPainter::Antialiasing);
|
||||
viewer->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
viewer->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
viewer->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);
|
||||
switchBtn->click();//切换结果图
|
||||
}
|
||||
~ImageWidget()
|
||||
{
|
||||
}
|
||||
void setTitle(const QString& text) {
|
||||
label->setText(text);
|
||||
}
|
||||
void createViewer(QString name)
|
||||
{
|
||||
map.insert(name, std::make_shared<QPixmap>(QPixmap()));
|
||||
switchBox.addItem(name);
|
||||
}
|
||||
public slots:
|
||||
//combobox切换槽
|
||||
void switchViewType(QString name)
|
||||
{
|
||||
QMutexLocker locker(&switchBoxMutex);
|
||||
auto& it = map.find(name);
|
||||
if (it == map.end())
|
||||
{
|
||||
QString listName;
|
||||
for (auto it = map.begin(); it != map.end(); ++it)listName.append(it.key() + ",");
|
||||
qDebug() << u8"未找到对应的viewer,输入:" << name << u8" 现有:"<< listName;
|
||||
return;
|
||||
}
|
||||
if (it.value()->isNull() == false)
|
||||
viewer->setImg(*it.value());
|
||||
else
|
||||
viewer->resetImage();
|
||||
|
||||
}
|
||||
void sendImg(QString type,QPixmap resImgInput)
|
||||
{
|
||||
std::string typer = type.toStdString();
|
||||
auto& it = map.find(type);
|
||||
if (it == map.end())
|
||||
{
|
||||
QString listName;
|
||||
for (auto it = map.begin(); it != map.end(); ++it)listName.append(it.key() + ",");
|
||||
qDebug() << u8"未找到对应的viewer,输入:" << type << u8" 现有:" << listName;
|
||||
return;
|
||||
}
|
||||
if (resImgInput.isNull()) {
|
||||
return;
|
||||
}
|
||||
it.value() = std::make_shared<QPixmap>(resImgInput);
|
||||
QMutexLocker locker(&switchBoxMutex);
|
||||
if (type == switchBox.currentText())
|
||||
showImgOnGraphicsView(resImgInput);
|
||||
}
|
||||
//无视当前类型直接显示
|
||||
void showImgOnGraphicsView(QPixmap imageMat) {
|
||||
viewer->setImg(imageMat);
|
||||
}
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent* event) override {
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
double scaleFactor = 1.15;
|
||||
if (event->angleDelta().y() < 0) {
|
||||
scaleFactor = 1.0 / scaleFactor;
|
||||
}
|
||||
|
||||
viewer->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();/以后改成存储当前图片
|
||||
}
|
||||
}
|
||||
int in = 0;
|
||||
QLabel* label;
|
||||
SonGraphicsView* viewer;
|
||||
QMap<QString,std::shared_ptr<QPixmap>> map;
|
||||
};
|
||||
//总
|
||||
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",int xPos = -1,int yPos = -1)
|
||||
{
|
||||
ImageWidget* ImageView = new ImageWidget();
|
||||
ImageWidgetList.push_back(ImageView);
|
||||
if (nickName != "none")
|
||||
map.insert({ nickName,ImageView });
|
||||
ImageView->setTitle(nickName);
|
||||
if(xPos == -1 || yPos == -1)
|
||||
Layout->addWidget(ImageView);
|
||||
else
|
||||
Layout->addWidget(ImageView,yPos,xPos);
|
||||
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, QString nickName, QString _type ="null")
|
||||
{
|
||||
if (map.find(nickName) == map.end())
|
||||
return false;
|
||||
if (_type == "null")
|
||||
map[nickName]->showImgOnGraphicsView(img);
|
||||
map[nickName]->sendImg(_type, img);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//预设
|
||||
Reference in New Issue
Block a user