Qt图像裁剪实时显示尺寸实现
鼠标按着红线左右拖动,红框中实时体现左右侧拖动了多少像素,红线之间剩余多少
#include "myqgraphicsview.h"MyQGraphicsView::MyQGraphicsView(QWidget *parent) : QGraphicsView(parent)
{m_graphics_scene = new QGraphicsScene(this);setScene(m_graphics_scene);// 设置视图属性setRenderHint(QPainter::Antialiasing);setDragMode(QGraphicsView::NoDrag);setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);// 初始化裁剪线m_graphics_line_item_left = m_graphics_scene->addLine(0, 0, 0, 1, QPen(Qt::red, 2));m_graphics_line_item_right = m_graphics_scene->addLine(1, 0, 1, 1, QPen(Qt::red, 2));// 初始化尺寸标签m_size_label = new QLabel(this);//m_size_label->setStyleSheet("QLabel { background-color : white; color : black; }");m_size_label->setAlignment(Qt::AlignCenter);m_size_label->hide();// 默认不显示任何线m_graphics_line_item_left->hide();m_graphics_line_item_right->hide();
}
void MyQGraphicsView::set_image(const QPixmap &pixmap)
{if(m_is_first_load_image){m_is_first_load_image =false;m_graphics_scene->clear();m_graphics_pixmap_item = m_graphics_scene->addPixmap(pixmap);m_graphics_scene->setSceneRect(pixmap.rect());// 重新初始化裁剪线m_graphics_line_item_left = m_graphics_scene->addLine(0, 0, 0, pixmap.height(), QPen(Qt::red, 10));m_graphics_line_item_right = m_graphics_scene->addLine(pixmap.width(), 0, pixmap.width(), pixmap.height(), QPen(Qt::red, 10));// 显示线m_graphics_line_item_left->show();m_graphics_line_item_right->show();m_pure_image_width = pixmap.width();// 设置初始裁剪区域为整个图像m_crop_rect = pixmap.rect();update_size_label();}else{delete m_graphics_pixmap_item; m_graphics_pixmap_item =nullptr;m_graphics_pixmap_item = m_graphics_scene->addPixmap(pixmap);m_graphics_line_item_left->show();m_graphics_line_item_right->show();}
}QRect MyQGraphicsView::get_crop_rect()const{return m_crop_rect;}void MyQGraphicsView::mousePressEvent(QMouseEvent *event)
{QPointF scenePos = mapToScene(event->pos());// 检查是否点击了左线或右线if (m_graphics_line_item_left->contains(scenePos)){m_dragging_left = true;}else if (m_graphics_line_item_right->contains(scenePos)){m_dragging_right = true;}QGraphicsView::mousePressEvent(event);
}void MyQGraphicsView::mouseMoveEvent(QMouseEvent *event)
{if (m_dragging_left || m_dragging_right){QPointF scenePos = mapToScene(event->pos());int x = qBound(0.0, scenePos.x(), m_graphics_scene->width());if (m_dragging_left) // 左线不能超过右线{x = qMin(x, (int)m_graphics_line_item_right->line().x1() - 1);m_graphics_line_item_left->setLine(x, 0, x, m_graphics_scene->height());}else if (m_dragging_right) // 右线不能超过左线{x = qMax(x, (int)m_graphics_line_item_left->line().x1() + 1);m_graphics_line_item_right->setLine(x, 0, x, m_graphics_scene->height());}// 更新裁剪矩形m_crop_rect.setLeft(m_graphics_line_item_left->line().x1());m_crop_rect.setRight(m_graphics_line_item_right->line().x1());m_crop_rect.setTop(0);m_crop_rect.setBottom(m_graphics_scene->height());update_size_label();emit cropSizeChanged(m_crop_rect.width(), m_crop_rect.height());emit signal_left_right(m_crop_rect.x(), m_pure_image_width - m_crop_rect.x() - m_crop_rect.width());}QGraphicsView::mouseMoveEvent(event);
}
void MyQGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{m_dragging_left = false;m_dragging_right = false;QGraphicsView::mouseReleaseEvent(event);
}
void MyQGraphicsView::resizeEvent(QResizeEvent *event)
{QGraphicsView::resizeEvent(event);fitInView(m_graphics_scene->sceneRect(), Qt::KeepAspectRatio);update_size_label_position();
}
void MyQGraphicsView::update_size_label()
{int width = m_crop_rect.width();int height = m_crop_rect.height();m_size_label->setText(QString("left=%0 [%1 x %2] right=%3").arg(m_crop_rect.x()).arg(width).arg(height).arg(m_pure_image_width - m_crop_rect.x()- m_crop_rect.width()));m_size_label->adjustSize();update_size_label_position();m_size_label->show();
}
void MyQGraphicsView::update_size_label_position()
{QRectF rect = mapFromScene(m_crop_rect).boundingRect();m_size_label->move(rect.center().x() - m_size_label->width()/2,rect.top() - m_size_label->height() - 5);
}
#ifndef MYQGRAPHICSVIEW_H
#define MYQGRAPHICSVIEW_H#include <QThread>
#include <QObject>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QGraphicsRectItem>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QPen>
#include <QGraphicsLineItem>
#include <QMouseEvent>class MyQGraphicsView : public QGraphicsView
{Q_OBJECT
public:explicit MyQGraphicsView(QWidget *parent = nullptr);void set_image(const QPixmap &pixmap);QRect get_crop_rect() const;protected:void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void resizeEvent(QResizeEvent *event) override;private:void update_size_label();void update_size_label_position();signals:void cropSizeChanged(int width, int height);/*** @brief signal_left_right* @param left: 原图左侧被裁剪了N个像素* @param right: 原图右侧被裁剪了N个像素*/void signal_left_right(int left, int right);private:QGraphicsScene *m_graphics_scene = nullptr; //创建一个图像视场QGraphicsPixmapItem *m_graphics_pixmap_item = nullptr; //图像对象QGraphicsLineItem *m_graphics_line_item_left = nullptr; //左路侧竖红线对象QGraphicsLineItem *m_graphics_line_item_right = nullptr; //右侧竖红线对象QLabel *m_size_label = nullptr; //裁剪后的图像矩形尺寸显示QRect m_crop_rect; //裁剪后的图像矩形尺寸bool m_dragging_left = false; //左侧线是否选中bool m_dragging_right = false; //右侧线是否选中int m_pure_image_width = 0; //原始图像的宽度bool m_is_first_load_image = true;
};#endif // MYQGRAPHICSVIEW_H