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
    评论
可以使用Qt的QGraphicsView和QGraphicsScene来实现一个可以滑动的时间轴。具体步骤如下: 1. 创建一个QGraphicsView对象和一个QGraphicsScene对象。 2. 在QGraphicsScene添加一个QGraphicsLineItem来表示时间轴的线。 3. 在QGraphicsScene添加多个QGraphicsRectItem或者QGraphicsEllipseItem来表示时间轴上的事件。 4. 使用QGraphicsView来显示QGraphicsScene。 5. 实现鼠标拖动事件,在拖动的过程改变QGraphicsScene的位置,从而实现时间轴的滑动。 下面是一个简单的示例代码,实现一个可以滑动的时间轴: ```cpp #include <QtWidgets> class TimeLineView : public QGraphicsView { public: TimeLineView(QWidget* parent = nullptr) : QGraphicsView(parent) { setDragMode(QGraphicsView::ScrollHandDrag); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setRenderHint(QPainter::Antialiasing); setViewportUpdateMode(QGraphicsView::FullViewportUpdate); setSceneRect(0, 0, 1000, 100); QGraphicsLineItem* line = new QGraphicsLineItem(0, 50, 1000, 50); line->setPen(QPen(Qt::black, 2)); scene()->addItem(line); for (int i = 0; i < 10; ++i) { QGraphicsRectItem* rect = new QGraphicsRectItem(i * 100, 25, 50, 50); rect->setBrush(QBrush(Qt::red)); scene()->addItem(rect); } } protected: void mousePressEvent(QMouseEvent* event) override { if (event->button() == Qt::LeftButton) { m_lastPos = event->pos(); } QGraphicsView::mousePressEvent(event); } void mouseMoveEvent(QMouseEvent* event) override { if (event->buttons() & Qt::LeftButton) { QPointF delta = mapToScene(event->pos()) - mapToScene(m_lastPos); m_lastPos = event->pos(); horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x()); } QGraphicsView::mouseMoveEvent(event); } private: QPoint m_lastPos; }; int main(int argc, char* argv[]) { QApplication app(argc, argv); TimeLineView view; view.show(); return app.exec(); } ``` 在这个示例代码,我们创建了一个自定义的QGraphicsView类TimeLineView,其我们重载了鼠标拖动事件,在拖动的过程改变了水平滚动条的值,从而实现了时间轴的滑动。在构造函数,我们创建了一个QGraphicsScene对象,并在其添加了一个QGraphicsLineItem和多个QGraphicsRectItem来表示时间轴上的线和事件。最后,我们将QGraphicsView设置为只能以手持模式拖动,并禁用了水平和垂直滚动条。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值