Rishabh Goel
Rishabh Goel

Reputation: 178

How to properly read touch events and get position on a QWidget Qt

I'm trying to develop a game controller for an android app in qt and am having some issues. The controller works perfectly fine when I just use QMouseEvents instead of QTouchEvents, but the problem is that it doesn't support multiple points of contact. There doesn't seem to be an equivalent for QWidget::mousePressEvent for touch events. I was told to use QWidget::event instead as such.

bool GameController::event(QEvent* event)
{
    switch(event->type())
    {
    case QEvent::TouchBegin: 
         //Do something...
         break;
    case QEvent::TouchEnd: 
         //Do something else...
         break;
    case QEvent::TouchUpdate:
         //Do something else...
         break;
    }
    return QWidget::event(event);
}

The problem with this is that I'm unable to use event->touchPoints() to get the position of the touches because it doesn't know that its a touch event. How can I properly read touch events?

Upvotes: 1

Views: 1914

Answers (2)

tsragravorogh
tsragravorogh

Reputation: 3153

All of the protected functions/event handlers for various types of events for QWidget (e.g. QWidget::showEvent(QShowEvent*), QWidget::hideEvent(QHideEvent*)) are specializations of the general QWidget::event() method for your convenience.

And QWidget::event() itself is implemented through the QObject::eventFilter() virtual method. You can read more about it here - https://doc.qt.io/qt-5/qobject.html#eventFilter. Through the help of bool eventFilter(QObject *obj, QEvent *ev) override, you can get notified about all QEvents that are sent to your QObect as well as to other objects through the use of QObject::installEventFilter().

In the body of your implementation of QObject::eventFilter() you check the type of the event as well as its receiver and then after that do either static_cast or dynamic_cast as described by @Jeremy Friesner to access the methods specific to that event. Using this powerful mechanism you can implement your own specialized event functions, as well as custom signals, if you want your sub-classed QObject to emit a signal in case of an event.

Upvotes: 0

Jeremy Friesner
Jeremy Friesner

Reputation: 73121

The compiler may not know it's a touch event, but as long as you know it, you can downcast:

case QEvent::TouchBegin:
{
   QTouchEvent * te = static_cast<QTouchEvent *>(event);
   // now you can call te->touchPoints(), etc here
}

Note that the above code will invoke undefined behavior if event isn't actually pointing to a QTouchEvent (or a subclass thereof), so only use static_cast when you can 100% guarantee that event is actually a QTouchEvent (which AFAIK you can in this scenario).

For cases where you can't guarantee the downcast will be valid, you can use dynamic_cast instead, which is smart enough to check the pointed-to-object and return NULL if it isn't actually valid to downcast to that type:

case QEvent::TouchBegin:
{
   QTouchEvent * te = dynamic_cast<QTouchEvent *>(event);
   if (te)
   {
      // now you can call te->touchPoints(), etc here
   }
}

Of course that runtime check costs a few CPU cycles, so don't use dynamic_cast unless you need to.

Upvotes: 3

Related Questions