鼠标按着红线左右拖动,红框中实时体现左右侧拖动了多少像素,红线之间剩余多少

cpp
#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);
}
cpp
#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