123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- #include "ImageView.h"
- #include <QPainter>
- #include <QDebug>
- #include <QGraphicsPixmapItem>
- #include <QScrollBar>
- #include <QMenu>
- #include <QFileDialog>
- #include <QDateTime>
- #include <QMessageBox>
- #define VIEW_CENTER viewport()->rect().center()
- #define VIEW_WIDTH viewport()->rect().width()
- #define VIEW_HEIGHT viewport()->rect().height()
- ImageView::ImageView(QWidget* parent) :
- QGraphicsView(parent),
- m_imageOffset(0, 0),
- m_bMouseTranslate(false),
- m_isDrawing(false),
- m_curDrawing(false),
- m_currentPathItem(nullptr)
- {
- m_pRuleLine = nullptr;
- setScene(new QGraphicsScene(this));
- setRenderHint(QPainter::SmoothPixmapTransform);
- setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
- this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- this->resize(parent->size());
- }
- ImageView::~ImageView()
- {
- }
- void ImageView::setPixmap(const QPixmap& newPixmap) {
- this->m_pixmap = newPixmap;
- scene()->clear();
- m_pixmapItem = scene()->addPixmap(m_pixmap);
- m_pixmapItem->setZValue(1);
- QPointF pixmapCenter(m_pixmap.width() / 2.0, m_pixmap.height() / 2.0);
- m_pixmapItem->setPos(-pixmapCenter);
- QRectF sceneRect(-pixmapCenter.x(), -pixmapCenter.y(), m_pixmap.width(), m_pixmap.height());
- scene()->setSceneRect(sceneRect);
- setSceneRect(scene()->itemsBoundingRect());
- this->resize(m_pixmap.width(), m_pixmap.height());
- m_imageOffset = QPoint(0, 0); // 重置图片偏移量为(0, 0)
- setCursor(Qt::ArrowCursor);
- update(); // 触发重绘
- }
- void ImageView::setCurPixmap(const QPixmap& newPixmap) {
- if (this->m_pixmap.isNull()) {
- this->m_pixmap = newPixmap;
- scene()->clear();
- m_pixmapItem = scene()->addPixmap(m_pixmap);
- m_pixmapItem->setZValue(1);
- QPointF pixmapCenter(m_pixmap.width() / 2.0, m_pixmap.height() / 2.0);
- m_pixmapItem->setPos(-pixmapCenter);
- QRectF sceneRect(-pixmapCenter.x(), -pixmapCenter.y(), m_pixmap.width(), m_pixmap.height());
- scene()->setSceneRect(sceneRect);
- setSceneRect(scene()->itemsBoundingRect());
- //this->resize(m_pixmap.width(), m_pixmap.height());
- m_imageOffset = QPoint(0, 0); // 重置图片偏移量为(0, 0)
- setCursor(Qt::ArrowCursor);
- update(); // 触发重绘
- }
- else {
- this->m_pixmap = newPixmap;
- m_pixmapItem->setPixmap(m_pixmap);
- }
- }
- void ImageView::startRuler()
- {
- if (nullptr == m_pRuleLine) {
- m_pRuleLine = new DraggableLine(QLineF(0, 0, 50, 50));
- m_pRuleLine->setPen(QPen(Qt::red, 2));
- m_pRuleLine->setZValue(2);
- scene()->addItem(m_pRuleLine);
- }
- }
- void ImageView::endRuler()
- {
- if (nullptr != m_pRuleLine) {
- scene()->removeItem(m_pRuleLine);
- delete m_pRuleLine;
- m_pRuleLine = nullptr;
- }
- }
- bool ImageView::rulerVisibale()
- {
- if (nullptr == m_pRuleLine)
- return false;
- else
- return true;
- }
- void ImageView::paintEvent(QPaintEvent* event) {
- QGraphicsView::paintEvent(event);
- }
- void ImageView::mousePressEvent(QMouseEvent* event) {
- if (event->button() == Qt::LeftButton) {
- // 当光标底下没有 item 时,才能移动
- QPointF point = mapToScene(event->pos());
- if (scene()->itemAt(point, transform()) != m_pRuleLine) {
- setCursor(Qt::OpenHandCursor);
- m_bMouseTranslate = true;
- m_lastMousePos = event->pos();
- }
- }
- else if (event->button() == Qt::RightButton) {
- m_rightClickPressPos = event->pos();
- m_rightButtonPressed = true;
- }
- QGraphicsView::mousePressEvent(event);
- }
- void ImageView::mouseMoveEvent(QMouseEvent* event) {
- if (m_bMouseTranslate) {
- // 计算鼠标当前位置与上次位置的差值
- QPointF delta = event->pos() - m_lastMousePos;
- // 平移视图
- horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
- verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
- m_lastMousePos = event->pos(); // 更新鼠标位置
- }
- else if ((event->buttons() & Qt::RightButton) && m_isDrawing && m_rightButtonPressed) {
- if (!m_curDrawing && (event->pos() - m_rightClickPressPos).manhattanLength() > 5) {
- m_curDrawing = true;
- // 根据初始位置开始绘制路径
- QPointF scenePos = mapToScene(m_rightClickPressPos);
- m_currentPath = QPainterPath(scenePos);
- m_currentPathItem = new QGraphicsPathItem();
- m_currentPathItem->setPen(QPen(Qt::red, 2));
- m_currentPathItem->setPath(m_currentPath);
- m_currentPathItem->setZValue(2);
- scene()->addItem(m_currentPathItem);
- m_drawnPaths.append(m_currentPathItem);
- }
- // 如果已经处于绘制状态,则继续添加点
- if (m_curDrawing && m_currentPathItem) {
- QPointF scenePos = mapToScene(event->pos());
- m_currentPath.lineTo(scenePos);
- m_currentPathItem->setPath(m_currentPath);
- }
- event->accept();
- return;
- }
- QGraphicsView::mouseMoveEvent(event);
- }
- void ImageView::mouseReleaseEvent(QMouseEvent* event) {
- if (event->button() == Qt::LeftButton) {
- setCursor(Qt::ArrowCursor); // 松开时恢复为箭头
- m_bMouseTranslate = false;
- }
- else if (event->button() == Qt::RightButton && m_rightButtonPressed) {
- if (!m_curDrawing) {
- // 右键点击(无拖动),弹出菜单
- QMenu menu(this);
- QAction* act1 = menu.addAction(tr("保存当前窗口图片"));
- QAction* act2 = menu.addAction(tr("清除"));
- connect(act1, &QAction::triggered, this, [this]() {
- saveImage();
- });
- connect(act2, &QAction::triggered, this, [this]() {
- clearDrawnLines();
- });
- menu.exec(event->globalPos());
- }
- else {
- // 绘制结束
- m_currentPathItem = nullptr;
- m_curDrawing = false;
- }
- // 恢复状态
- m_rightButtonPressed = false;
- event->accept();
- return;
- }
- QGraphicsView::mouseReleaseEvent(event);
- }
- void ImageView::wheelEvent(QWheelEvent* event)
- {
- if (event->orientation() == Qt::Vertical) {
- event->ignore(); // 忽略竖直滚轮事件(即禁用滚动条滑动)
- return;
- }
- event->accept();
- }
- void ImageView::saveImage()
- {
- // 使用当前时间生成默认文件名
- QString defaultFileName = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss") + ".png";
- QString fileName = QFileDialog::getSaveFileName(
- this,
- tr("保存图片"),
- QDir::homePath() + "/" + defaultFileName, // 默认路径为用户目录,文件名为当前时间
- tr("PNG 文件 (*.png);;JPEG 文件 (*.jpg);;所有文件 (*)")
- );
- if (!fileName.isEmpty()) {
- QImage image(viewport()->size(), QImage::Format_ARGB32);
- image.fill(Qt::white);
- QPainter painter(&image);
- this->render(&painter);
- if (!image.save(fileName)) {
- QMessageBox::warning(this, tr("保存失败"), tr("无法保存图片到指定路径。"));
- }
- else {
- QMessageBox::information(this, tr("保存成功"), tr("图片已成功保存到:") + fileName);
- }
- painter.end();
- }
- }
- void ImageView::clearDrawnLines()
- {
- qDeleteAll(m_drawnPaths);
- m_drawnPaths.clear();
- }
|