Qt 터치스크린 QTouch 또는 마우스로 지도 축소, 매눈 지도, 동적 지도

실현 원리:widget의 이벤트를 수신하고paint Event는 지도를 다시 그립니다. 좌표 비례 같은 것도 축소와 편이량 변환에 따라 계산할 수 있습니다...간단하고 거칠습니다. 코드에 직접 올리세요!헤더 파일:
#ifndef CPROJECTIONPICTURE_H
#define CPROJECTIONPICTURE_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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 
#include 
#include 
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<

    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
//    {
//        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 
#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;
        }

좋은 웹페이지 즐겨찾기