Qt 之QWebEngineView 触摸屏联动

需求

  • 1.在嵌入式系统上,使用QWebEngineView打开网页后,通过手指滑动触摸屏,网页上下滚动。
  • 2.在手指离开屏幕时, 继续滑动一段距离,类似手机app效果

思路

  • 将手指滑动的动作,映射成滚轮事件,然后滚轮滑动距离跟手指滑动距离相关
  • 手指离开屏幕后,启动定时器,继续滑动

QMouseEvent

注意: QMouseEvent只涉及鼠标点击,释放,移动。 不涉及滚轮。滚轮需要QWheeEvent来处理。

  • 构造一个QMousetEvent
QMouseEvent::QMouseEvent(QEvent::Type type, 					
                        const QPointF &localPos, 
                        const QPointF &screenPos, 
                        Qt::MouseButton button, 
                        Qt::MouseButtons buttons, 
                        Qt::KeyboardModifiers modifiers)
//QEvent::Type -> QEvent::MouseButtonPress/MouseButtonRelease/MouseButtonDblClick/MouseMove
//localPos     -> 鼠标光标相对于Widget的位置
//button       -> 从Qt::MouseButton的枚举值
//buttons      -> 鼠标按键的状态,通过QMousetEvent::buttons()返回
//modifiers    -> 键盘的状态, 枚举值

针对鼠标移动事件, 如果tracking状态时关闭的,那么鼠标移动事件,需要鼠标按键按下同时,鼠标移动才会被触发。当鼠标追踪标志开启后,不需要鼠标按下

If mouse tracking is switched off, mouse move events only occur if a mouse button is pressed while the mouse is being moved. If mouse tracking is switched on, mouse move events occur even if no mouse button is pressed.

  • trachking开启前
void Widget::mouseMoveEvent(QMouseEvent *event)
{
   
    // 这里必须使用buttons()
    if(event->buttons() & Qt::LeftButton) //进行的按位与
    {
    
       ···
    }
}
  • tracking开启后
setMouseTracking(true);

初始Demo

  • 增加MousePress事件处理: 记录按下标志 + 起始Y距离
  • 增加MouseRelease事件处理 : 标志清零
  • 增加MouseMove事件处理: 在里面将转换成滚轮事件,并计算滚动距离
  • 增加QEvent::ChildAdded事件处理
#include "htwebengine.h"
#include <QMouseEvent>
#include <QOpenGLWidget>
#include <QDebug>
#include <QWheelEvent>
#include <QCoreApplication>

HTWebEngine::HTWebEngine(QWidget *parent) : QWebEngineView(parent)
{
   
    installEventFilter(this);
    m_mouseIsPress = false;
}

bool HTWebEngine::eventFilter(QObject *obj, QEvent *ev)
{
   
    if (ev->type() == QEvent::MouseButtonPress) {
   
        if (!m_mouseIsPress) 							//手指按下
        {
   
            m_mouseIsPress = true;						//手指按下标志为真
            QMouseEvent *event = static_cast<QMouseEvent*>(ev);	 //转换为MouseEvent
            m_mousePrvY = event->y();                   //上一次点击的Y的位置
            m_mousePressPosY = event->y();              //点击的Y的位置
            m_mousePressPosX = event->x();              //点击的X的位置
            return true;							    //处理结束		
        }
    }
    else if (ev->type() == QEvent::MouseButtonRelease)	//手指离开
    {
   
        if ( m_mouseIsPress ) 
        {
   
            QMouseEvent *event = static_cast<QMouseEvent*>(ev);
            if (event->y() == m_mousePressPosY) 	    //如果手指离开的距离和之前点击的距离相同,说明是点击事件,			
            {
   
                QMouseEvent doubleEvent(QEvent::MouseButtonPress,event->localPos(),event->button(),event->buttons(),Qt::NoModifier);             //构造一个mouse event 对象, construct a moust event object.
                QCoreApplication::sendEvent(obj,&doubleEvent);  //继续传递
            }
            m_mouseIsPress = false;						//将按下标志为清空
        }
    }
    else if (ev->type() == QEvent::ChildAdded) 
    {
   
        QChildEvent *child_ev = static_cast<QChildEvent*>(ev);
        QObject *w = child_ev->child();
        if (w) {
   
            w->installEventFilter(this);
        }
    }
    else if (ev->type() == QEvent::MouseMove) 			//如果时移动
    {
   
        if (m_mouseIsPress) {
   							//且之前的按下标志位为真
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(ev);
            int delta = mouseEvent->y() - m_mousePrvY;   //滑动距离
            m_mousePrvY = mouseEvent->y();				 //更新当前的Y值
            QWheelEvent event(QPointF(m_mousePressPosX ,m_mousePressPosY),delta,Qt::NoButton,Qt::NoModifier);  //滑动距离delta
            QCoreApplication::sendEvent(obj,&event);
        }
    }

    return QWebEngineView::eventFilter(obj, ev);
}

增加惯性滑动Demo

增加惯性滑动

  • 在什么时间点触发: QEvent::MouseButtonRelease<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 5.9.0 的 QWebEngineView 控件是基于 Chromium 内核的 Web 浏览器控件,其默认情况下不支持触摸屏拖动地图。如果您需要在 QWebEngineView 控件中加载地图并支持触屏拖动,可以考虑使用 JavaScript 和 HTML5 技术来实现。 具体实现方式如下: 1. 在 HTML5 中使用 Google Maps API 加载地图,并启用触摸屏拖动功能。 ```html <!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title>Google Maps JavaScript API v3 Example: Map Simple</title> <style> html, body, #map_canvas { margin: 0; padding: 0; height: 100%; } </style> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> var map; function initialize() { var mapOptions = { zoom: 8, center: new google.maps.LatLng(-34.397, 150.644), mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); map.setOptions({draggable: true, zoomControl: true, scrollwheel: true, disableDoubleClickZoom: false}); } google.maps.event.addDomListener(window, 'load', initialize); </script> </head> <body> <div id="map_canvas"></div> </body> </html> ``` 2. 在 Qt 的代码中,使用 QWebChannel 将 JavaScript 对象暴露给 Qt 代码,并在 QWebEngineView 的 loadFinished 信号触发后,通过 QWebChannel 的 call 方法调用 JavaScript 对象的方法来启用触摸屏拖动功能。 ```cpp #include <QWebChannel> #include <QWebEngineView> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWebEngineView view; view.load(QUrl("file:///path/to/your/html/file")); // Create a QWebChannel object and expose a QObject to JavaScript QWebChannel channel; QObject *obj = new QObject(); channel.registerObject("qtObj", obj); view.page()->setWebChannel(&channel); // When the page is loaded, call the JavaScript function to enable touch drag QObject::connect(&view, &QWebEngineView::loadFinished, [&]() { view.page()->runJavaScript("qtObj.enableTouchDrag();"); }); view.show(); return app.exec(); } ``` 在 JavaScript 中,可以定义一个名为 qtObj 的对象,并在该对象中定义一个名为 enableTouchDrag 的方法来启用触摸屏拖动功能。 ```javascript var qtObj = { enableTouchDrag: function() { var mapDiv = document.getElementById("map_canvas"); mapDiv.addEventListener("touchstart", function(e) { if (e.touches.length == 1) { var touch = e.touches[0]; var mouseEvent = new MouseEvent("mousedown", { clientX: touch.clientX, clientY: touch.clientY }); mapDiv.dispatchEvent(mouseEvent); } }, false); mapDiv.addEventListener("touchmove", function(e) { if (e.touches.length == 1) { e.preventDefault(); var touch = e.touches[0]; var mouseEvent = new MouseEvent("mousemove", { clientX: touch.clientX, clientY: touch.clientY }); mapDiv.dispatchEvent(mouseEvent); } }, false); mapDiv.addEventListener("touchend", function(e) { if (e.touches.length == 0) { var mouseEvent = new MouseEvent("mouseup", {}); mapDiv.dispatchEvent(mouseEvent); } }, false); } }; ``` 这样就可以在 QWebEngineView 控件中加载地图并支持触屏拖动了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值