由于这显然是一个Qt错误,唯一的解决办法就是解决它。点击和保持可以很容易地检测到,如下所示:
:
#ifndef RMCWRAPPER_H
#define RMCWRAPPER_H
#include <QObject>
#include <QPoint>
#include <QTime>
class QWidget;
class TapAndHoldWrapper : public QObject
{
Q_OBJECT
public:
TapAndHoldWrapper( QWidget* parent, QObject* receiver = NULL, const char* slot = NULL );
~TapAndHoldWrapper();
bool eventFilter(QObject *obj, QEvent *event);
signals:
void requested( QPoint globalPos );
private:
QWidget* m_parent;
QTime m_pressedAt;
QPoint m_pressedPos;
};
#endif
:
#include "gesture.h"
#include <QWidget>
#include <QEvent>
#include <QGestureEvent>
#include <QAbstractScrollArea>
#if QT_VERSION >= QT_VERSION_CHECK( 5, 12, 0 )
// handle this manually, see https://bugreports.qt.io/browse/QTBUG-73326
#define HANDLE_TAP_AND_HOLD_MANUALLY
#endif
TapAndHoldWrapper::TapAndHoldWrapper( QWidget* parent, QObject* receiver, const char* slot ) :
QObject( parent ),
m_parent( parent )
{
// optional in Qt 5.6. Required in Qt 5.12
QAbstractScrollArea* area = dynamic_cast< QAbstractScrollArea* >( m_parent );
if ( area )
m_parent = area->viewport();
m_parent->installEventFilter( this );
#ifndef HANDLE_TAP_AND_HOLD_MANUALLY
m_parent->grabGesture( Qt::TapAndHoldGesture );
#endif
if ( receiver && slot )
{
connect( this, SIGNAL(requested(QPoint)), receiver, slot );
}
}
TapAndHoldWrapper::~TapAndHoldWrapper()
{
}
bool TapAndHoldWrapper::eventFilter(QObject *obj, QEvent *event)
{
#ifdef HANDLE_TAP_AND_HOLD_MANUALLY
if ( event->type() == QEvent::MouseButtonPress && obj == m_parent )
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>( event );
if ( mouseEvent->button() == Qt::LeftButton )
{
m_pressedAt = QTime::currentTime();
m_pressedPos = mouseEvent->globalPos();
}
}
else if ( event->type() == QEvent::MouseButtonRelease && obj == m_parent )
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>( event );
if ( mouseEvent->button() == Qt::LeftButton )
{
int elapsed = m_pressedAt.msecsTo( QTime::currentTime() );
if ( elapsed >= 500 )
{
if ( std::abs( m_pressedPos.x() - mouseEvent->globalPos().x() ) < 10 &&
std::abs( m_pressedPos.y() - mouseEvent->globalPos().y() ) < 10 )
{
emit requested( mouseEvent->globalPos() );
}
// else, mouse moved too much, it's not a tap and
}
}
}
#else
if ( event->type() == QEvent::Gesture && obj == m_parent )
{
QGestureEvent *gestevent = static_cast<QGestureEvent *>(event);
if (QGesture *gest = gestevent->gesture(Qt::TapAndHoldGesture))
{
if ( gest && gest->state() == Qt::GestureFinished )
{
QPoint globalPos = gest->hotSpot().toPoint();
emit requested( globalPos );
return true;
}
}
}
#endif
// standard event processing
return QObject::eventFilter(obj, event);
}
请注意,事件过滤器必须安装在视口上,而不是小部件本身。