Qt 触摸屏QTouch 或者鼠标实现 地图缩放,鹰眼地图,动态地图

实现原理:接收widget的事件,paintEvent重绘地图,坐标比例什么的也是根据缩放和偏移量转换计算得出…
简单粗暴,直接上代码吧!
头文件:

#ifndef CPROJECTIONPICTURE_H
#define CPROJECTIONPICTURE_H
#include <QWidget>
#include <QGestureEvent>
#include <QPanGesture>
#include <QPinchGesture>
#include <QSwipeGesture>
#include <QGestureEvent>
#include <QGestureEvent>
#include <QPointF>
#include <QTime>
#include <QPushButton>
#include <QGraphicsView>

class CProjectionPicture : public QWidget
{
    Q_OBJECT
public:
    CProjectionPicture(QWidget *parent = 0);

    void setPicture(QPixmap & image);

protected:

    bool event(QEvent *event) ;
    void paintEvent(QPaintEvent *event) ;
    void resizeEvent(QResizeEvent *e) ;


public Q_SLOTS:

    void zoom(qreal scale); // 缩放 - scaleFactor:缩放的比例因子
    void translate(QPointF delta);  // 平移
    void doubleClick();// 双击

signals:
    void SignalDoPress(qreal x, qreal y);
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;

    QPushButton * button;

    QGraphicsView * view;



};
#endif // CPROJECTIONPICTURE_H

CPP:

#include "cprojectionpicture.h"
#include <QPainter>
#include <QDebug>
#include <iostream>
using namespace std;


CProjectionPicture::CProjectionPicture(QWidget *parent)
    : QWidget(parent),
    horizontalOffset(0),
    verticalOffset(0),
    scaleFactor(1),
    m_translateButton(Qt::LeftButton),
    m_bMouseTranslate(false),
    m_zoomDelta(0.2)
{
    //setWindowFlags(Qt::FramelessWindowHint);
    this->setFocusPolicy(Qt::ClickFocus);
    setFixedSize(1312,850);
    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;
}
void CProjectionPicture::setPicture(QPixmap &image)
{

//    QGraphicsView vvv;
//    QGraphicsScene scene;
//    vvv.setScene(scene);

//    QGraphicsPixmapItem item;
//    item.scale();
//    scene.addItem(item);
//    item

    currentImage = image;//image.convertToFormat(QImage::Format_RGB888);
    pic_fix_width=currentImage.width();
    pic_fix_height=currentImage.height();

    scaleFactor=1;
    button = new QPushButton(this);
    button->setGeometry(100,100,100,100);
    button->setText("button1");


    update();
}


bool CProjectionPicture::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 scale = 1;
//            if()
//            {
//                currentScaleFactor =
//            }

            qreal currentScaleFactor=wheelEvent->delta() > 0?1.05:0.95;

            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);
            if(button->x() < x  && x < button->x()+button->width() &&
                    button->y() < y &&  y <button->y()+button->height())
            {

                qDebug("button1 pressed!!!");
            }

            return true;
        }

        case QEvent::MouseMove:
        {
            QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);

//            if(mouseEvent->MouseButtonPress)
//            {
                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:
        {
        //1.获取第一次点击屏幕时的坐标
        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.05:0.95;

                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());
                        if(scaleFactor>1.5)
                        {
                            zoom(true);
                        }
                        else
                        {
                             zoom(true);
                        }
                        touch_success=true;
                    }

                }
                else
                {
                   touch_success=false;
                   qreal sx= touchPoint0.pos().rx();
                   qreal sy= touchPoint0.pos().ry();
                   qreal rx=(sx-horizontalOffset)*scaleFactor;
                   qreal ry=(sy-verticalOffset)*scaleFactor;
                   emit SignalDoPress(rx,ry);
                }
            }
        }

        touch_status=0;


            return true;
        }
        default:
            break;
        }

    return QWidget::event(event);
}

void CProjectionPicture::paintEvent(QPaintEvent*)
{
    QPainter painter(this);

    QPixmap image = currentImage;
//    scaleFactor = 1.5;
    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();
//    const qreal wh = height();
//    const qreal ww = width();
    //cout<<iw<<" "<<ih<<" "<<wh<<" "<<ww<<endl;

    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);

//    button->resize(scaleFactor*button->size());
//    button->move(horizontalOffset,verticalOffset);
//    painter.drawImage(-200,-2\0,image);

}



void CProjectionPicture::resizeEvent(QResizeEvent*e)
{
    update();
    QWidget::resizeEvent(e);
}


// 缩放 - scaleFactor:缩放的比例因子
void CProjectionPicture::zoom(qreal scale)
{

//    qreal scalecur = scale ? scaleFactor+0.2 : scaleFactor-0.2;


//    scale ? scalecu = scaleFactor+0.1 : scalecu = scaleFactor-0.1;
    qreal scalecur=scaleFactor*scale;
    QPointF current_center=current_zoom_center;

//    if(scalecur<fix_scaleFactor)
//    {
//        scalecur=fix_scaleFactor;
//        horizontalOffset=0;
//        verticalOffset=0;
//    }
   if(scalecur<1)
    {
        scalecur=1;
        horizontalOffset=0;
        verticalOffset=0;
    }
    else if(scalecur>2)
    {
        scalecur=2;

        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;
//    QImage img(QString("tvm.bkg.00.chn.%1.jpg").arg(scaleFactor));
//    currentImage = img.convertToFormat(QImage::Format_RGB888);
//    pic_fix_width=currentImage.width();
//    pic_fix_height=currentImage.height();
    update();
}

// 平移
void CProjectionPicture::translate(QPointF delta)
{

    horizontalOffset +=delta.x();
    verticalOffset += delta.y();
    update();
}

void CProjectionPicture::doubleClick()
{
    scaleFactor > 1 ? scaleFactor = 1 : scaleFactor = 2;

    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;
    }

//    QImage img(QString("tvm.bkg.00.chn.%1.jpg").arg(scaleFactor));
//    currentImage = img.convertToFormat(QImage::Format_RGB888);
//    pic_fix_width=currentImage.width();
//    pic_fix_height=currentImage.height();

    update();

}

使用:
main.cpp

#include "widget.h"
#include <QApplication>
#include "cprojectionpicture.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    Widget w;
//    w.show();
    CProjectionPicture cpij;
    QPixmap img("ditu.jpg");//一张高清地图
    cpij.setPicture(img);
    cpij.show();


    return a.exec();
}

关于坐标比例问题:文章中代码实现了地图缩放拖动后的点击地图上的点相对屏幕坐标还是不变

 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);
            if(button->x() < x  && x < button->x()+button->width() &&
                    button->y() < y &&  y <button->y()+button->height())
            {

                qDebug("button1 pressed!!!");
            }

            return true;
        }
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值