Qt触摸屏双指缩放和单指移动界面(支持嵌入式设备)

本文介绍的QGraphicsView的双指缩放,QWidget更简单,可以参考当前内容。

1、首先需要打开触摸屏功能。

this->setAttribute(Qt::WA_AcceptTouchEvents);

2、在event事件管理器中接收触摸屏的三个事件,TouchBegin、TouchUpdate和TouchEnd。

3、判断单点触摸还是多点触摸。

4、如果多点触摸,通过比较前后两次两点间触摸位置来判断是放大还是缩小。

5、多点触摸时,会存在抖动情况,需要做防抖处理。

6、如果是单点触摸,通过比较手指放上去的位置和手指拖动时的位置来设置界面滚动条的位置。

代码:

属性设置

clike 复制代码
    this->setAttribute(Qt::WA_AcceptTouchEvents);

缩放和移动逻辑

clike 复制代码
bool MGraaphicsView::event(QEvent *e)
{
    static int index = 0;
    switch (e->type()) {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
    {
        qDebug() <<"CProjectionPicture::event"<<e->type();
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
        if (touchPoints.count() == 2) {
            //缩放
            const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
            const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
            qreal currentScaleFactor = QLineF(touchPoint0.pos(), touchPoint1.pos()).length()
                    / QLineF(touchPoint0.startPos(), touchPoint1.startPos()).length();
            if (currentScaleFactor  > _lastScaleFactor)
                index++;
            else if (currentScaleFactor  < _lastScaleFactor)
                index--;
            if (index == 5)//超过5次放大,则认为有效.防抖操作
            {
                index = 0;
                zoomOnce(true);
            }
            else if (index == -5)
            {
                index = 0;
                zoomOnce(false);
            }
            qDebug()<<index<<currentScaleFactor<<_lastScaleFactor;
            _lastScaleFactor = currentScaleFactor;
            update();
        }
        else if (touchPoints.count() == 1)
        {//移动
            const QTouchEvent::TouchPoint &touchPoint = touchPoints.first();
            if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchEnd)
                _startScenePos = mapToScene(touchPoint.pos().toPoint());

            if (e->type() == QEvent::TouchUpdate)
            {
                QPointF endScenePos = mapToScene(touchPoint.pos().toPoint());
                QPointF delta = endScenePos - _startScenePos;
                int oposx = this->horizontalScrollBar()->value();
                int oposy = this->verticalScrollBar()->value();
                int nposx = oposx - delta.x();
                int nposy = oposy - delta.y();
                this->horizontalScrollBar()->setValue(nposx);
                this->verticalScrollBar()->setValue(nposy);
            }

            qDebug()<<"====="<<_startScenePos<<touchPoint.pos();
        }
        if (touchEvent->touchPointStates() & Qt::TouchPointReleased)
        {
            qDebug()<<"Qt::TouchPointReleased";
        }
        return true;//一定不要调QGraphicsView::event(e);否则手指触摸会经常失效
    }
    default:
        break;
    }

    return QGraphicsView::event(e);
}

//缩放

clike 复制代码
void MGraaphicsView::zoomOnce(bool increase)
{
    if (increase)
        setZoom(1);
    else
        setZoom(-1);
}

void MGraaphicsView::setZoom(int val)
{
    if (val > 0)
    {
        m_zoom++;
        auto scaleValue = qPow(2, m_zoom);
        setTransform(QTransform::fromScale(scaleValue, scaleValue));
    }
    else
    {
        m_zoom--;
        auto scaleValue = qPow(2, m_zoom);
        setTransform(QTransform::fromScale(scaleValue, scaleValue));
    }
}
相关推荐
ajassi20003 小时前
开源 C++ QT Widget 开发(十五)多媒体--音频播放
linux·c++·qt·开源
零点零一4 小时前
VS+QT的编程开发工作:关于QT VS tools的使用 qt的官方帮助
开发语言·qt
空灵之海11 小时前
Ubuntu系统安全合规配置
linux·ubuntu·系统安全·1024程序员节
牵牛老人11 小时前
Qt C++ 复杂界面处理:巧用覆盖层突破复杂界面处理难题之一
数据库·c++·qt
ChindongX13 小时前
CString(MFC/ATL 框架)和 QString(Qt 框架)
qt·mfc
清朝牢弟13 小时前
Win系统下配置PCL库第一步之下载Visual Studio和Qt 5.15.2(超详细)
c++·qt·visual studio
QT 小鲜肉14 小时前
【QT随笔】结合应用案例一文完美概括QT中的队列(Queue)
c++·笔记·qt·学习方法·ai编程
SNAKEpc1213817 小时前
QML和Qt Quick
c++·qt
PH_modest17 小时前
【Qt跬步积累】—— 初识Qt
开发语言·qt
刘梓谦19 小时前
如何在Qt中使用周立功USB转CAN卡
开发语言·qt·zlg·周立功