Qt4中实现一个可触摸滑动的区域

最近在开发项目中需要一个可触摸切换菜单的区域,过程中遇到了一些问题:如触摸驱动上报鼠标抬起异常,滑动区域中的按钮会拦截点击事件,滑动区域中的按钮不响应等。通过自己不断调试,结合查看Qt源码和网上资料一一将问题解决。
在Qt5中有QScroller类可实现此效果,可参考https://blog.csdn.net/qq_41949352/article/details/95595749。
在Qt4中没有这个类,于是自己继承QScrollArea重写其中的鼠标事件来实现。定义Scrollwidget类,scrollwidget.h如下:

#ifndef SCROLLWIDGET_H
#define SCROLLWIDGET_H

/****************************
 * 滑动区域,继承自QScrollArea,添加此类后将控件提升为Scrollwidget,
 * 并调用m_installEventFilter函数,即可实现滑动,并响应区域中的按钮事件 
 * AUTHOR("dzj <juzone@126.com>");
***********************/

#include <QScrollArea>
#include <qdebug.h>
#include <QAbstractButton>
#include <QMouseEvent>


class Scrollwidget : public QScrollArea
{
private:
    bool isFirstdrag;
    int move_x;
    int move_y;
    int move_speed;
    QPoint start_point;
public:
    explicit Scrollwidget(QWidget *parent = 0);
    void m_installEventFilter();
protected:
    void mousePressEvent(QMouseEvent *event);  //鼠标点击事件
    void mouseMoveEvent(QMouseEvent *event);  //鼠标移动事件
    void mouseReleaseEvent(QMouseEvent *event);  //鼠标释放事件
    bool eventFilter(QObject *obj, QEvent *event);
};

#endif // SCROLLWIDGET_H

scrollwidget.cpp如下:

#include "scrollwidget.h"

Scrollwidget::Scrollwidget(QWidget *parent) : QScrollArea(parent)
{
    move_x = 0;
    move_y = 0;
    move_speed = 1;
}

void Scrollwidget::m_installEventFilter()
{
    foreach (QObject *obj, this->findChildren<QAbstractButton *>()) {
        obj->installEventFilter(this);
    }
}

bool Scrollwidget::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *event = static_cast<QMouseEvent *>(event);
        this->mousePressEvent(event);
        return false;
    }else if(event->type() == QEvent::MouseButtonRelease){
        QMouseEvent *event = static_cast<QMouseEvent *>(event);
        this->mousePressEvent(event);
        return false;
    }else {
        return QObject::eventFilter(obj, event);
    }
}

void Scrollwidget::mousePressEvent(QMouseEvent *event)  //鼠标点击事件
{
    isFirstdrag = 1;
    move_x = move_x > 0 ? move_x : 0;
    move_x = move_x < this->width() ? move_x : this->width();
    move_y = move_y > 0 ? move_y : 0;
    move_y = move_y < this->height() ? move_y : this->height();
}

void Scrollwidget::mouseMoveEvent(QMouseEvent *event)  //鼠标移动事件
{
    if(isFirstdrag)
    {
        isFirstdrag = 0;
        start_point = event->globalPos();
    }else{
        int dx = event->globalPos().x() - start_point.x();
        int dy = event->globalPos().y() - start_point.y();
        move_x += dx * move_speed;
        move_y += dy * move_speed;
        this->ensureVisible(move_x,move_y);
    }
}

void Scrollwidget::mouseReleaseEvent(QMouseEvent *event)  //鼠标释放事件
{
    isFirstdrag = 1;
}

参考链接:https://www.cnblogs.com/findumars/p/6152886.html 跳转.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值