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));
    }
}
相关推荐
十五年专注C++开发2 小时前
QStyleItemDelegate:自定义列表控件类神器
qt·model·view·delegate
无小道3 小时前
Qt——事件简单介绍
开发语言·前端·qt
mengzhi啊6 小时前
QUndoView 本质是一个 Qt 界面控件(继承自 QListView),专门适配 QUndoStack
qt
编程小白20266 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
深蓝海拓7 小时前
PySide6,QCoreApplication::aboutToQuit与QtQore.qAddPostRoutine:退出前后的清理工作
笔记·python·qt·学习·pyqt
薛定谔的猫喵喵7 小时前
天然气压力能利用系统综合性评价平台:基于Python和PyQt5的AHP与模糊综合评价集成应用
开发语言·python·qt
云中飞鸿7 小时前
linux中qt安装
开发语言·qt
少控科技8 小时前
QT第6个程序 - 网页内容摘取
开发语言·qt
开开心心就好9 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
stevenson_aspdotnet9 小时前
QT5.15.12 编译备忘
qt