最近有个Qt的项目碰到问题,问题是这样的:
要使Qt的窗口内容支持drag移动,即按住鼠标左键在窗口里移动时,窗口的滚动条和内容随着鼠标的移动而移动。
实现的方法实现一个类,此类派生自QScrollArea,安装事件过滤器,对鼠标的事件进行处理来实现内容的移动。
代码如下:
头文件
#include
<QScrollArea> <QPoint>
class
{
MyScrollArea : public QScrollArea
这样就可以使用这个类来做窗口的parent,这样里面的内容就支持拖动了。
Q_OBJECT
public:
QWidget * parent =NULL );MyScrollArea(
~MyScrollArea(){};
protected
:bool eventFilter(QObject *obj, QEvent *evt);
private
: bool mMoveStart ; bool mContinousMove ; QPoint mMousePoint ;
};
cpp文件
#include <QMouseEvent>
#include <QScrollBar>
#include "myscrollarea.h"
MyScrollArea::MyScrollArea(QWidget* parent)
: QScrollArea(parent)
,mMoveStart(false)
{
installEventFilter
(this ); }
bool MSCScrollArea::eventFilter(QObject *obj, QEvent *evt)
{
if (evt->type() == QEvent::MouseMove) {
QMouseEvent* me = (QMouseEvent*) evt;
if ((me->buttons() & Qt::LeftButton)) {
if (!mMoveStart) {
mMoveStart = true;
mContinousMove =false;
mMousePoint = me->globalPos();
}
else {
QScrollBar* scrollBar = verticalScrollBar();
QPoint p = me->globalPos();
int offset = p.y() - mMousePoint.y();
if( !mContinousMove && ( offset > -10 && offset < 10 ) )
return false;
mContinousMove = true;
scrollBar->setValue(scrollBar->value() - offset);
mMousePoint = p;
}
return true;
}
}
else if (evt->type() == QEvent::MouseButtonRelease) {
mMoveStart = false;
}
return QObject::eventFilter(obj, evt);
}
但我在使用过程中发现一个问题,如果窗口里的控件也实现了鼠标的move或release事件,那么这时候这2个事件就不会传到MyScrollArea,这样就会出现bug,但后来找到了解决办法,就是在控件的这两个事件的最后加上一行代码,
event->ignore();
这样就解决了,因为如果是将事件ignore掉的话,此事件还会忘父控件上传,这样的话,每层都ignore掉,最后会传到MyScrollArea里,这样MyScrollArea也就能正常处理鼠标事件了。
#include