0

I am struggling with getting multi-touch to work on a couple of QWidgets that I have added to a QGraphicsView. I have created a subclass of QWidget in which I set up a QGraphicsScene and QGraphicsView. This is my (test) subclass of QWidget:

#include "qttest1.h"

#include <QtWidgets>
#include <QTouchEvent>

qttest1::qttest1(QWidget *parent)
    : QWidget(parent)
{
    setEnabled(true);

    if(!QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
        setAttribute(Qt::WA_NativeWindow);

    setAttribute(Qt::WA_AcceptTouchEvents);

    scene = new QGraphicsScene(this);
    scene->setSceneRect(0, 0, 1920, 1080);
    graphicsView = new QGraphicsView(scene, this);
    graphicsView->setRenderHints(QPainter::Antialiasing);
    graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    graphicsView->setAttribute(Qt::WA_AcceptTouchEvents);
    graphicsView->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);

    QBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(graphicsView);

    setLayout(layout);
}

qttest1::~qttest1() {}

void qttest1::showGraphics() 
{
    for(int i = 0; i < 10; i++)
    {
        Dial *dial = new QDial();

        dial->move(i * 120 + 50, 200);
        dial->resize(120, 120);
        dial->setAttribute(Qt::WA_AcceptTouchEvents);

        QGraphicsProxyWidget *proxy = scene->addWidget(dial);
        proxy->setAcceptTouchEvents(true);
    }
}

This is my main:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);

    QRect rect = app.desktop()->screenGeometry();

    qttest1 test;
    test.resize(rect.width(), rect.height());
    test.showFullScreen();
    test.showGraphics();

    return app.exec(); 
}

I know the code isn't pretty and probably leaking a bit, but the point is to try to get multi-touch to work.

I can see and use every kind of widget I add to the scene, but as soon as I touch a dial it swallows every touch that comes after the first. Which makes the dial jump between several positions. What I want is that every dial (or any type of widget) can be used individually and at the same time. I am using QT 5.0.2, Windows 8 with a monitor that supports up to 10 touches.

Finitely Failed
  • 119
  • 3
  • 14

1 Answers1

1

The Qt docs state : -

Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent() for widgets and QGraphicsItem::sceneEvent() for items in a graphics view to receive touch events.

With that, I believe that you need to handle the QEvent::TouchBegin, QEvent::TouchUpdate and QEvent::TouchEnd events, which I don't see in the code you've posted.

Qt may handle the first touch for you, but it's not going to know what you want to do with the second, third, fourth etc. simultaneous touches. For example, you may want your app to do any of the following with the second touch moving: -

1) Rotate the object that the first item is over

2) Scale the object that the first item is over

3) Select the second item

4) Translate the view

5) etc.

So, you need to handle the consecutive touches to do what you want it to do. Also, you may want to look at Gestures in Qt.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • I have seen multitouch work inside a QGraphicsView in one of the examples, as well in a small example I wrote. However that is not the issue, the issue is that widgets does not work simultaneously. E.g. if I add two QSlide to a QGraphicsScene and try to use them at the same time (using touch) only the one that I first touch will work. There seem to be an issue even when I test this not using a QGraphicsScene (and QGraphicsView) but I have not test it enough to draw any real conclusions. Are you saying I have to implement my own widgets/graphisitems to get it work as I want? – Finitely Failed Jul 05 '13 at 06:29
  • 1
    QSlide isn't a QGraphicsItem or Object, are you using it through QGraphicsProxyWidget? If so, there are various things that don't get passed through to the actual widget and this may be one of them. As for your question, yes I would expect you need to inherit from the GraphicsItem to define its specific behaviour in response to multi-touch; at least that's what I did when I used it in Qt 4.8 – TheDarkKnight Jul 05 '13 at 07:46
  • Yes, I use it through QGraphicsProxyWidget. I can accept that things like touches wont get passed to widgets inside QGraphicsScene, but what I find weird is that they do, e.g. if I add a QSlide to a QGraphicsScene it works as expected with touches, but using two QSlides at the same time wont work. – Finitely Failed Jul 05 '13 at 07:58
  • 1
    I recall having had a similar problem with proxy items that multi-touch didn't work correctly. We contacted Qt at the time, but never got a satisfactory reply. That was about a year and half ago, so things may have changed in Qt 5. I did, however implement the handling for the touch, as described in my answer and found it worked with regular QGraphicsItems, but not proxy widgets. – TheDarkKnight Jul 05 '13 at 08:03