Qt触摸放大、缩小、拖拽图像

这篇具有很好参考价值的文章主要介绍了Qt触摸放大、缩小、拖拽图像。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现原理:接收widget的事件,paintEvent重绘地图,坐标比例什么的也是根据缩放和偏移量转换计算得出…
简单粗暴,直接上代码吧!文章来源地址https://www.toymoban.com/news/detail-546432.html

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLoggingCategory>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPixmap>
#include <QObject>
#include <QWidget>
#include <QGraphicsView>
#include <QEvent>
#include <QTouchEvent>
#include <QDebug>
#include <QMouseEvent>
#include <QPixmap>
#include <QTime>
#include <QPushButton>


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void setPicture(QPixmap& image);
    void zoom(qreal scale);
    void translate(QPointF delta);
    void doubleClick();
protected:
    bool event(QEvent *event) override;

    void paintEvent(QPaintEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
private:
    QPixmap currentImage;
    int touch_status;//0 end and default,1press 2press move


    qreal horizontalOffset;//水平偏移
    qreal verticalOffset;//垂直偏移

    qreal scaleFactor;//放大倍率

    Qt::MouseButton m_translateButton;  // 平移按钮
    bool m_bMouseTranslate;
    qreal m_zoomDelta;  // 缩放的增量
    QPoint m_lastMousePos;  // 鼠标最后按下的位置

    int pic_fix_width;//图片宽
    int pic_fix_height;//图片长

    QPointF current_zoom_center;
    QPointF previous_touch_point0;
    QPointF previous_touch_point1;
    QTime touch_time;
    bool touch_success;

    Ui::MainWindow *ui;   
};
#endif // MAINWINDOW_H

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
    QPixmap img("/home/one/01-QtTest/TouchTest3/brightenhance.bmp");
    //QPixmap img("./brightenhance.bmp");
    setPicture(img);
    setAttribute(Qt::WA_AcceptTouchEvents,true);
    setFocusPolicy(Qt::ClickFocus);
    grabGesture(Qt::PanGesture);
    grabGesture(Qt::PinchGesture);
    grabGesture(Qt::SwipeGesture);
    current_zoom_center.setX((qreal)width()/2);
    current_zoom_center.setY((qreal)height()/2);
    touch_time.start();

    touch_status=0;
    touch_success=false;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setPicture(QPixmap &image)
{
    currentImage = image;//image.convertToFormat(QImage::Format_RGB888);
    pic_fix_width=currentImage.width();
    pic_fix_height=currentImage.height();

    scaleFactor=1;
    update();
}

void MainWindow::zoom(qreal scale)
{
    qreal scalecur=scaleFactor*scale;
    QPointF current_center=current_zoom_center;

    if(scalecur < 1)
    {
        scalecur = 1;
        horizontalOffset=0;
        verticalOffset=0;
    }
    else if(scalecur > 3)
    {
        scalecur = 3;
        horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scalecur/scaleFactor;
        verticalOffset = current_center.ry()  -(current_center.ry() - verticalOffset)*scalecur/scaleFactor;
    }
    else
    {
        horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scalecur/scaleFactor;
        verticalOffset = current_center.ry()  -(current_center.ry() - verticalOffset)*scalecur/scaleFactor;
    }

    scaleFactor = scalecur;
    update();
}

void MainWindow::translate(QPointF delta)
{
    horizontalOffset +=delta.x();
    verticalOffset += delta.y();
    update();
}

void MainWindow::doubleClick()
{
    scaleFactor = scaleFactor > 1 ? scaleFactor = 1 : scaleFactor = 3;
    if(scaleFactor == 1)
    {
        horizontalOffset=0;
        verticalOffset=0;
    }
    else
    {
        QPointF current_center=current_zoom_center;
        horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scaleFactor;
        verticalOffset = current_center.ry()  -(current_center.ry() - verticalOffset)*scaleFactor;
    }
    update();
}

bool MainWindow::event(QEvent *event)
{
    switch (event->type()) {
    case QEvent::Wheel:
    {
        QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
        current_zoom_center.setX(wheelEvent->pos().x());
        current_zoom_center.setY(wheelEvent->pos().y());
        qreal currentScaleFactor = wheelEvent->delta() > 0 ? 1.1 : 0.9;
        zoom(currentScaleFactor);
        return true;
    }
    case QEvent::MouseButtonPress:
    {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        previous_touch_point0.setX(mouseEvent->pos().x());
        previous_touch_point0.setY(mouseEvent->pos().y());
        uint x = (mouseEvent->pos().x() - horizontalOffset) / scaleFactor;
        uint y = (mouseEvent->pos().y() - verticalOffset) / scaleFactor;

        qDebug("x = %d",x);
        qDebug("y = %d",y);
        return true;
    }
    case QEvent::MouseMove:
    {
        QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
         QPointF delta;
         delta.setX(mouseEvent->pos().x() - previous_touch_point0.x());
         delta.setY(mouseEvent->pos().y() - previous_touch_point0.y());
         translate(delta);
         previous_touch_point0.setX(mouseEvent->pos().x());
         previous_touch_point0.setY(mouseEvent->pos().y());
         return true;
    }
    case QEvent::MouseButtonDblClick:
    {
        QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);

        current_zoom_center.setX(mouseEvent->pos().x());
        current_zoom_center.setY(mouseEvent->pos().y());
        doubleClick();
        return true;
    }
    case QEvent::TouchBegin:
    {
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
        if(touchPoints.count() == 1)
        {
            if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
            {
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());

                touch_status = 1;
            }
        }
        else if(touchPoints.count() == 2)
        {
            if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
            {
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
                const QTouchEvent::TouchPoint& touchPoint1 = touchPoints.last();
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());
                previous_touch_point1.setX(touchPoint1.pos().x());
                previous_touch_point1.setY(touchPoint1.pos().y());
                touch_status = 1;
            }
        }
        return true;
    }
    case QEvent::TouchUpdate:
    {
        // 2.点击后的动作
        qDebug() <<"TouchUpdate";
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
        if (touchPoints.count() == 2)
        {
            if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
            {
                touch_status=1;
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
                const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());
                previous_touch_point1.setX(touchPoint1.pos().x());
                previous_touch_point1.setY(touchPoint1.pos().y());
                // 确定两点之前的中心点的坐标,后续区域缩放的时候使用这个中心点作为 缩放定位
                current_zoom_center.setX((touchPoint0.pos().rx()+touchPoint1.pos().rx())/2);
                current_zoom_center.setY((touchPoint0.pos().ry()+touchPoint1.pos().ry())/2);
            }
            else if(touchEvent->touchPointStates() & Qt::TouchPointMoved)
            {
                touch_status=2;
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
                const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
                current_zoom_center.setX((touchPoint0.pos().rx()+touchPoint1.pos().rx())/2);
                current_zoom_center.setY((touchPoint0.pos().ry()+touchPoint1.pos().ry())/2);
                qreal  qlines = QLineF(touchPoint0.pos(), touchPoint1.pos()).length()
                                    / QLineF(previous_touch_point0, previous_touch_point1).length();
                qreal currentScaleFactor=qlines > 1 ? 1.1 : 0.9;

                zoom(currentScaleFactor);
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());
                previous_touch_point1.setX(touchPoint1.pos().x());
                previous_touch_point1.setY(touchPoint1.pos().y());
            }
            else if(touchEvent->touchPointStates() & Qt::TouchPointReleased)
            {
                touch_status = 0;
            }
        }
        else if (touchPoints.count() == 1)
        {
            if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
            {
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());
                touch_status=1;
            }
            else if(touchEvent->touchPointStates() & Qt::TouchPointMoved)
            {
                touch_status=2;
                const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();

                QPointF delta;
                delta.setX(touchPoint0.pos().x()-previous_touch_point0.x());
                delta.setY(touchPoint0.pos().y()-previous_touch_point0.y());
                translate(delta);
                previous_touch_point0.setX(touchPoint0.pos().x());
                previous_touch_point0.setY(touchPoint0.pos().y());
            }
            else if(touchEvent->touchPointStates() & Qt::TouchPointReleased)
            {

            }
        }

        return true;
    }
    case QEvent::TouchEnd:
    {
        //3. 松开
        qDebug() <<"TouchEnd";
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
        if(touchPoints.count()==1)
        {
            const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
            if(touch_status==1)
            {
                int timecount= touch_time.restart();
                if(timecount<500)
                {
                    if(!touch_success)
                    {
                        current_zoom_center.setX(touchPoint0.pos().rx());
                        current_zoom_center.setY(touchPoint0.pos().ry());

                        zoom(true);

                        touch_success=true;
                    }
                }

            }
        }
        touch_status=0;
        return true;
    }
    default:
        break;
    }
    return QWidget::event(event);
}



void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPixmap image = currentImage;
    if(!image.isNull())
    {
        image = image.scaled(this->width()*scaleFactor, this->height()*scaleFactor, Qt::KeepAspectRatio, Qt::FastTransformation);
    }
    const qreal iw = image.width();
    const qreal ih = image.height();
    if(horizontalOffset > 0)
    {
        horizontalOffset=0;
    }
    if(verticalOffset>0)
    {
        verticalOffset=0;
    }
    if(this->width()-horizontalOffset>iw)
    {
        horizontalOffset=this->width()-iw;
    }
    if(this->height()-verticalOffset>ih)
    {
        verticalOffset=this->height()-ih;
    }

    painter.drawPixmap(horizontalOffset, verticalOffset, image);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    update();
    QWidget::resizeEvent(event);
}

到了这里,关于Qt触摸放大、缩小、拖拽图像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包