This commit is contained in:
RCi
2025-06-11 10:00:09 +08:00
parent 85129b9c0e
commit b936e86e19
430 changed files with 44143 additions and 188182 deletions
+177 -176
View File
@@ -27,231 +27,215 @@
#include <qgraphicsproxywidget.h>
class ImageWidgetManager;
//单画幅
class SonGraphicsView :
public QGraphicsView
class SonGraphicsView : public QGraphicsView
{
//Q_OBJECT
public:
QString name;
QGraphicsScene* scene;
SonGraphicsView(QString nameIn):
name (nameIn)
explicit SonGraphicsView(const QString& nameIn)
: name(nameIn),
scene(new QGraphicsScene(this)),
rectGroup(new QGraphicsItemGroup()),
imageWidth(1),
imageHeight(1),
m_isPan(false),
rightClicked(false)
{
QMutexLocker locker(&mutex);
setDragMode(QGraphicsView::DragMode::NoDrag);
setDragMode(QGraphicsView::NoDrag);
setInteractive(false);
setEnabled(false);
setObjectName("SonGraphicsView");
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);
setScene(scene);
setStyleSheet(R"(
QGraphicsView#SonGraphicsView {
background: transparent;
background-image: url(:/icon/icon/waitting.png);
background-repeat: no-repeat;
background-position: center center;
})");
}
void setImg(QPixmap pixmap)
{
showImg(pixmap);
void setImg(const QPixmap& pixmap) {
showImg(pixmap);
}
void resetImage()
{
void resetImage() {
QMutexLocker locker(&mutex);
scene->clear();
pixmapItem = nullptr;
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)
void wheelEvent(QWheelEvent* event) override {
if (scene->items().isEmpty())
return;
QPoint numDegrees = event->angleDelta() / 8;
if (!numDegrees.isNull()) {
QPoint numSteps = numDegrees / 15;
zoom(numSteps);
zoom(numDegrees / 15);
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);
//}
void keyPressEvent(QKeyEvent* event) override {
// 可以添加快捷键重置视图等操作
}
virtual void mousePressEvent(QMouseEvent* event) override
{
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));
rectItem->setPen(QPen(Qt::red, 5, Qt::DashLine));
rectGroup->addToGroup(rectItem);
this->update();
return;
update();
}
else {
event->ignore();
}
event->ignore();
}
virtual void mouseMoveEvent(QMouseEvent* event) override
{
void mouseMoveEvent(QMouseEvent* event) override {
currentPos = mapToScene(event->pos());
if (rightClicked == true)
{
if (rightClicked && rectItem) {
QPointF endPos = currentPos;
// 计算矩形的宽度和高度
qreal width = endPos.x() - startPos.x();
qreal height = endPos.y() - startPos.y();26;
rectItem->setTransformOriginPoint(startPos);
qreal height = endPos.y() - startPos.y();
rectItem->setRect(startPos.x(), startPos.y(), width, height);
}
if (m_isPan) {
pan(event->pos());
event->accept();
return;
}
event->ignore();
else {
event->ignore();
}
}
virtual void mouseReleaseEvent(QMouseEvent* event) override
{
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;
qreal height = endPos.y() - startPos.y();
deleteAllRect();
if (width != 0 && height != 0) {
double scaleRate = std::max(width == 0 ? 1.0 : rect().width() / width,
height == 0 ? 1.0 : rect().height() / height);
scale(scaleRate, scaleRate);
centerOn(startPos + QPointF(width / 2, height / 2));
}
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);
event->ignore();
}
}
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;
QString name;
QGraphicsScene* scene = nullptr;
QGraphicsItemGroup* rectGroup = nullptr;
QGraphicsRectItem* rectItem = nullptr;
// QLabel* imgLabel = nullptr; // 删除
QGraphicsPixmapItem* pixmapItem = nullptr;
int imageWidth = 1;
int imageHeight = 1;
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);
}
bool rightClicked = false;
imgLabel->setFixedSize(imageWidth, imageHeight);
imgLabel->setPixmap(img);
setSceneRect(rect);
this->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
bool m_isPan = false;
QPoint m_prevPan;
QMutex mutex;
void showImg(const QPixmap& img) {
QMutexLocker locker(&mutex);
setEnabled(true);
setMouseTracking(true);
imageWidth = img.width();
imageHeight = img.height();
if (pixmapItem) {
scene->removeItem(pixmapItem);
delete pixmapItem;
pixmapItem = nullptr;
}
catch (...) {
qDebug() << "showImg error";
pixmapItem = new QGraphicsPixmapItem(img);
scene->addItem(pixmapItem);
setSceneRect(img.rect());
fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
void zoom(const QPoint& factor) {
QRectF FOV = mapToScene(rect()).boundingRect();
float scaleX = static_cast<float>(imageWidth) / FOV.width();
float scaleY = static_cast<float>(imageHeight) / FOV.height();
double currentScale = transform().m11();
if ((factor.y() > 0 && currentScale > 10.0) || (factor.y() < 0 && currentScale < 0.1))
return;
scale(factor.y() > 0 ? 1.2 : 0.8, factor.y() > 0 ? 1.2 : 0.8);
}
void togglePan(bool pan, const QPoint& startPos = QPoint()) {
if (pan == m_isPan)
return;
m_isPan = pan;
m_prevPan = pan ? startPos : QPoint(0, 0);
setCursor(pan ? Qt::ClosedHandCursor : Qt::ArrowCursor);
}
void pan(const QPoint& panTo) {
QPoint delta = panTo - m_prevPan;
m_prevPan = panTo;
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
}
void deleteAllRect() {
if (!rectGroup)
return;
for (QGraphicsItem* item : rectGroup->childItems()) {
QGraphicsRectItem* rect = qgraphicsitem_cast<QGraphicsRectItem*>(item);
if (rect) {
rectGroup->removeFromGroup(rect);
scene->removeItem(rect);
delete rect;
}
}
}
bool m_isPan;
QPoint m_prevPan;
QLabel* imgLabel = nullptr;
int imageWidth = 1; int imageHeight = 1;
QMutex mutex;
};
//切换窗口 在切换时用pixmap替换现有的以实现
class ImageWidget : public QWidget {
Q_OBJECT
@@ -410,11 +394,26 @@ private:
QLabel* label;
SonGraphicsView* viewer;
QMap<QString,std::shared_ptr<QPixmap>> map;
std::map<QString, cv::Mat>imgShowMap;
};
//总
class ImageWidgetManager :public QWidget
{
public:
ImageWidget* createViewer(QString windowName, std::vector<std::string> viewers, int xPos = -1, int yPos = -1)
{
ImageWidget* ImageView = new ImageWidget();
ImageWidgetList.push_back(ImageView);
map.insert({ windowName,ImageView });
ImageView->setTitle(windowName);
if (xPos == -1 || yPos == -1)
Layout->addWidget(ImageView);
else
Layout->addWidget(ImageView, yPos, xPos);
for (auto& viewer : viewers)
ImageView->createViewer(QString::fromStdString(viewer));
return ImageView;
}
QGridLayout* Layout = new QGridLayout();
ImageWidgetManager()
{
@@ -424,23 +423,9 @@ public:
~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)
@@ -456,6 +441,22 @@ public:
return true;
}
bool new_showImg(QString windowName, QString _type,cv::Mat img)
{
if (map.find(windowName) == map.end()) {
qDebug() << "未找到对应窗口 请检查配置文件 windowName->" << windowName << " _type->" << _type;
return false;
}
//if (_type == "null")
// map[_type]->showImgOnGraphicsView(img);
//map[_type]->sendImg(_type, img);
return true;
}
private:
QMutex mutex;
QList< ImageWidget*>ImageWidgetList;
std::unordered_map<QString, ImageWidget*>map;
};
//预设