2

My problem is a poor resistive touch screen. When you drag your finger across the screen. The drag randomly cuts off because of the MouseButtonRelease event.

I would like to fix this by filtering the mouseEvents and removing all consecutive MouseButtonRelease and MouseButtonPress events if they occured e.g. less than 100ms appart. I would like to do this application-wide.

I already tried an eventFilter but it doesn't work properly. The stored MouseButtonRelease-events don't get sent to right objects. I installed this by installEventFilter(new MouseFilter(this)); at a widget, but all the mouse releases get lost.

Do you suggest a different approach or is there something wrong with my code?

#include "mousefilter.h"
#include <QApplication>
#include <QEvent>
#include <QMouseEvent>
#include <QTimer>

MouseFilter::MouseFilter(QObject *parent) :
  QObject(parent),
  storedEvent_(0)
{
}

void MouseFilter::send() {
  if ( storedEvent_ == 0 ) {
    return;
  }
  QApplication::sendEvent(parent(), storedEvent_);
  delete storedEvent_;
  storedEvent_ = 0;
}

bool MouseFilter::eventFilter(QObject *object, QEvent *event) {
  if ( event->type() == QEvent::MouseButtonRelease ) {
    QMouseEvent* release = static_cast<QMouseEvent*>(event);
    // Dalay the event
    storedEvent_ = new QMouseEvent(QEvent::MouseButtonRelease, release->pos(), release->globalPos(),
                                   release->button(), release->buttons(), release->modifiers());
    QTimer::singleShot(100, this, SLOT(send()));
    return true;
  }
  else if ( storedEvent_ != 0 && event->type() == QEvent::MouseButtonPress ) {
    // Clear stored release and ignore new press.
    delete storedEvent_;
    storedEvent_ = 0;
    return true;
  }

  return QObject::eventFilter(object, event);
}
Grina
  • 46
  • 4
  • Could you not use the operating system (touchscreen driver) to do this? That would be the more natural place for this behaviour (not the app), but I'd guess that this might be impractical. – Unapiedra Dec 05 '11 at 14:14
  • Does this post help? http://www.qtcentre.org/threads/21999-How-to-delay-a-Signal?p=107183#post107183 She suggests, using `enterEvent` and `leaveEvent` in connection with `QTimer`. – Unapiedra Dec 05 '11 at 14:16
  • You could also use "drag lock" mechanism (common on Mac OS X). It requires "double tap" to start draging and tap to end it. – Kamil Klimek Dec 05 '11 at 17:41
  • I think I'll just wait for the next touchscreen version for our device. It **should** be better. And you're right, the touchscreen driver would be more natural place for the filter. – Grina Dec 21 '11 at 13:50

1 Answers1

1

You are in a world of pain, been there. I complained to the hardware people and got nowhere.

An approach could be to do all the release events yourself. Basically whilst the finger is in contact you get an event (even if its stationary). Therefore based on that logic you can start a timer, then after 100ms of no touch events you fire off the mouse release.

The way that the QTimer works is that you can repeatedly call .start() and it will restart the count down.

Of course this is filled with problems in that its dependant on a magic number of 100ms, it reduces the responsiveness of your application and only fixes the bug in your application not system wide as it should be.

Phil Hannent
  • 12,047
  • 17
  • 71
  • 118