Hello,
I disable QwtPlotPanner when I'm dealing with QGestureEvents in my MouseZoomer class (a QwtPlotMagnifier) because the panner is executing in priority (I can't pinch) and I enable the panner when the gesture is finished (Qt::GestureFinished).
The panner is executing, IIRC, because Qt is generating mouse move events when pinching...
My probelm is that after finishing the pinching gesture, the panner is not immediately functional : only, the mouse cursor is moving when I'm moving my finger over the canvas !
I have to press elsewhere a second time to make the panner functionnal again !
Is there something else I can do to make the panner functionnal again after finishing the pinch gesture ?
I've already read the QwtPanner code and I didn't find what can be done to fix this issue. Should I manually post a mouse event after re-enabling the panner (and what kind of event) ? is it interesting to also grab gesture events in the panner and make this last do nothing between a pinch gesture ?
Thank you for any tip !
This is my MouseZoomer class (it zooms around mouse pointer and not the center of the canvas unlike the base class - and it handles both mouse wheel and pinch gestures) :
{
public:
explicit MouseZoomer
(QWidget* parent
= nullptr
);
protected:
void rescale(double factor) override;
protected:
/* zoom around this position (mouse or pinch gesture)
* (translated into an axis value of course) */
// panner need to be disabled while using the pinch gesture
QPointer<QwtPlotPanner> m_panner;
//double m_wheelSteps;
private:
bool gestureEvent(QGestureEvent* event);
};
class MouseZoomer : public QwtPlotMagnifier
{
typedef QwtPlotMagnifier Superclass;
public:
explicit MouseZoomer(QWidget* parent = nullptr);
void setPanner(QwtPlotPanner* const panner);
protected:
bool eventFilter( QObject *, QEvent * ) override;
void rescale(double factor) override;
void widgetWheelEvent(QWheelEvent* evt) override;
protected:
/* zoom around this position (mouse or pinch gesture)
* (translated into an axis value of course) */
QPointF m_mouseOrPinchPos;
// panner need to be disabled while using the pinch gesture
QPointer<QwtPlotPanner> m_panner;
//double m_wheelSteps;
private:
bool gestureEvent(QGestureEvent* event);
};
To copy to clipboard, switch view to plain text mode
MouseZoomer
::MouseZoomer(QWidget* parent
/*= nullptr*/) :{
// parent must be the QwtPlot's canvas widget
parent->grabGesture(Qt::PinchGesture);
}
{
m_panner = panner;
}
// overriden to handle pinch gesture on G1C devices
{
if (event
->type
() == QEvent::Gesture) {
return gestureEvent(static_cast<QGestureEvent*>(event));
}
// Make sure the rest of events are handled
return Superclass::eventFilter(obj, event);
}
bool MouseZoomer::gestureEvent(QGestureEvent* event)
{
if (QGesture* pinch = event->gesture(Qt::PinchGesture))
{
QPinchGesture* pinchGesture = static_cast<QPinchGesture*>(pinch);
if (m_panner && pinchGesture->state() == Qt::GestureStarted)
{
// panner need to be disabled when pinching starts
m_panner->setEnabled(false);
}
if (/*pinchGesture->state() == Qt::GestureUpdated &&*/
pinchGesture->changeFlags() & QPinchGesture::ScaleFactorChanged)
{
// gesture positions are defined in screen coordinate and not in widget one (unlike mouse positions)
const QPoint pos
(pinchGesture
->centerPoint
().
x(), pinchGesture
->centerPoint
().
y());
m_mouseOrPinchPos = canvas()->mapFromGlobal(pos);
rescale(pinchGesture->scaleFactor());
}
// panner can be re-enabled after finishing the pinch gesture
if (m_panner && pinchGesture->state() == Qt::GestureFinished)
{
m_panner->setEnabled(true);
}
}
return true;
}
MouseZoomer::MouseZoomer(QWidget* parent /*= nullptr*/) :
QwtPlotMagnifier(parent)
{
// parent must be the QwtPlot's canvas widget
parent->grabGesture(Qt::PinchGesture);
}
void MouseZoomer::setPanner(QwtPlotPanner* const panner)
{
m_panner = panner;
}
// overriden to handle pinch gesture on G1C devices
bool MouseZoomer::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::Gesture)
{
return gestureEvent(static_cast<QGestureEvent*>(event));
}
// Make sure the rest of events are handled
return Superclass::eventFilter(obj, event);
}
bool MouseZoomer::gestureEvent(QGestureEvent* event)
{
if (QGesture* pinch = event->gesture(Qt::PinchGesture))
{
QPinchGesture* pinchGesture = static_cast<QPinchGesture*>(pinch);
if (m_panner && pinchGesture->state() == Qt::GestureStarted)
{
// panner need to be disabled when pinching starts
m_panner->setEnabled(false);
}
if (/*pinchGesture->state() == Qt::GestureUpdated &&*/
pinchGesture->changeFlags() & QPinchGesture::ScaleFactorChanged)
{
// gesture positions are defined in screen coordinate and not in widget one (unlike mouse positions)
const QPoint pos(pinchGesture->centerPoint().x(), pinchGesture->centerPoint().y());
m_mouseOrPinchPos = canvas()->mapFromGlobal(pos);
rescale(pinchGesture->scaleFactor());
}
// panner can be re-enabled after finishing the pinch gesture
if (m_panner && pinchGesture->state() == Qt::GestureFinished)
{
m_panner->setEnabled(true);
}
}
return true;
}
To copy to clipboard, switch view to plain text mode
Bookmarks