需求
- 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<