最近在开发项目中需要一个可触摸切换菜单的区域,过程中遇到了一些问题:如触摸驱动上报鼠标抬起异常,滑动区域中的按钮会拦截点击事件,滑动区域中的按钮不响应等。通过自己不断调试,结合查看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 跳转.