PDA

View Full Version : touch event



leoalvesmachado
16th August 2010, 14:40
Hi folks.

I want to capture the "touch press" event - I mean, detect the exact time when the user touches my touch device, but does not lift or move the finger. It would be equivalent to the mouse press event, that is triggered on the exact moment the mouse button is pressed.
Today, my application detects the press only when, after a few seconds, "a circle" appears on the screen.

Is there a way to do that?

I'm using right know the QT 4.6.2 and Windows 7, compiling it with the Visual Studio compiler.

Thanks in advance for your help

Urthas
16th August 2010, 18:00
Well, as you say, it sounds like mousePressEvent is what you need to look at. Perhaps you could use the time() function from QDateTime in there. As for the current behavior, sounds like a timer is being started and if it exceeds a certain threshold before a release event is detected, it draws a circle; you'd have to post the code of your application's mousePressEvent to really get any meaningful feedback however.

Hope this helps.

leoalvesmachado
16th August 2010, 18:27
Hi Urthas
Thanks for your answer...
However, I'm already using the same event for mouse press and touch press - I believe QT was supposed to convert touch press events into mouse press. The problem is, when I press with the mouse, the event is caught right the way, in the same moment, but when I press with touch, it takes about 4 seconds to capture the event - it captures only when that white circle appears on the screen, in my touch position.
I don't know if it is a QT 4.6.2 limitation on Windows 7, or if I'm using the wrong event to catch the touch press... I've already tested the "touch press" feature in other development languages (wpf) and it works just as expected, however I still can't make it work on QT...

Urthas
16th August 2010, 19:06
Well, first of all, if you haven't already, I think it prudent to read the documentation for the QTouchEvent class thoroughly. It will tell you what hoops you need to jump through to make a widget respond to touch properly, and there is even a section on event handling. Another potentially useful thing to be aware of is the QEvent::Type enum.

leoalvesmachado
16th August 2010, 22:30
Well, I did a research for the last 4 hours and I still didn't get the answer :(. I've found the documentation of QTouchEvent and I've read how it works, but the code I've written didn't work as I expected.
I found this example, that might explain my problems:
http://doc.qt.nokia.com/4.6/multitouch-fingerpaint.html
I've followed the example, but trying to get the event on touch begin (That I thought it would be "the moment when the finger touches the screen) and without ignoring "TouchPointStationary", because that's just what I want to grab (single press, no movement). I've got the event twice - when I've released the finger from the screen (I thought the release was sopposed to be "touch end" :confused:) and after about 4 seconds, when the circle pointing my finger appears.

So, my conclusion until now is: Mouse press events and QTouchEvents don't work for my needs. Do I have any other option? Maybe if it is a bug in version 4.6.2 and it is fixed in 4.7, I could try a newer version. Is it fixed in 4.7?

Urthas
16th August 2010, 22:45
post your code?

leoalvesmachado
16th August 2010, 23:07
Se the link on my last post and copy all .h, .pro files, also main.cpp and mainwindow.cpp
This one is for scribblearea.cpp. I've only changed a few lines, to get the touch begin...

#include <QtGui>

#include "scribblearea.h"

ScribbleArea::ScribbleArea(QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_AcceptTouchEvents);
modified = false;

myPenColors
<< QColor("green")
<< QColor("purple")
<< QColor("red")
<< QColor("blue")
<< QColor("yellow")

<< QColor("pink")
<< QColor("orange")
<< QColor("brown")
<< QColor("grey")
<< QColor("black");
}

bool ScribbleArea::openImage(const QString &fileName)
{
QImage loadedImage;
if (!loadedImage.load(fileName))
return false;

QSize newSize = loadedImage.size().expandedTo(size());
resizeImage(&loadedImage, newSize);
image = loadedImage;
modified = false;
update();
return true;
}

bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
{
QImage visibleImage = image;
resizeImage(&visibleImage, size());

if (visibleImage.save(fileName, fileFormat)) {
modified = false;
return true;
} else {
return false;
}
}

void ScribbleArea::clearImage()
{
image.fill(qRgb(255, 255, 255));
modified = true;
update();
}

void ScribbleArea::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
const QRect rect = event->rect();
painter.drawImage(rect.topLeft(), image, rect);
}

void ScribbleArea::resizeEvent(QResizeEvent *event)
{
if (width() > image.width() || height() > image.height()) {
int newWidth = qMax(width() + 128, image.width());
int newHeight = qMax(height() + 128, image.height());
resizeImage(&image, QSize(newWidth, newHeight));
update();
}
QWidget::resizeEvent(event);
}

void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
{
if (image->size() == newSize)
return;

QImage newImage(newSize, QImage::Format_RGB32);
newImage.fill(qRgb(255, 255, 255));
QPainter painter(&newImage);
painter.drawImage(QPoint(0, 0), *image);
*image = newImage;
}

void ScribbleArea::print()
{
#ifndef QT_NO_PRINTER
QPrinter printer(QPrinter::HighResolution);

QPrintDialog *printDialog = new QPrintDialog(&printer, this);
if (printDialog->exec() == QDialog::Accepted) {
QPainter painter(&printer);
QRect rect = painter.viewport();
QSize size = image.size();
size.scale(rect.size(), Qt::KeepAspectRatio);
painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
painter.setWindow(image.rect());
painter.drawImage(0, 0, image);
}
#endif // QT_NO_PRINTER
}

bool ScribbleArea::event(QEvent *event)
{
//code to test "touch press event"
QMessageBox msgBox;
msgBox.setText("Touched!!");
//End of code to test "touch press event" 1st part
switch (event->type()) {
case QEvent::TouchBegin:
//code to test "touch press event"
msgBox.exec ();
break;
//End of code to test "touch press event"
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
switch (touchPoint.state()) {
case Qt::TouchPointStationary:
// don't do anything if this touch point hasn't moved
continue;
default:
{
QRectF rect = touchPoint.rect();
if (rect.isEmpty()) {
qreal diameter = qreal(50) * touchPoint.pressure();
rect.setSize(QSizeF(diameter, diameter));
}

QPainter painter(&image);
painter.setPen(Qt::NoPen);
painter.setBrush(myPenColors.at(touchPoint.id() % myPenColors.count()));
painter.drawEllipse(rect);
painter.end();

modified = true;
int rad = 2;
update(rect.toRect().adjusted(-rad,-rad, +rad, +rad));
}
break;
}
}
break;
}
default:
return QWidget::event(event);
}
return true;
}

Urthas
16th August 2010, 23:28
So the problem, then, is that the message box isn't being displayed, i.e., you're not detecting TouchBegin events?

leoalvesmachado
17th August 2010, 02:33
No, the problem is that I want the message to show in the exact time I touch the screen ("touch press", without moving or lifting the finger from the screen), and it just show after about 4s of touch press.

Urthas
17th August 2010, 18:21
I note in the QTouchEvent docs that
The QEvent::TouchBegin event is propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it.

It seems to me that your filter is consuming it. Perhaps
return QWidget::event(event); should be the last statement in your method, and not confined to a default case. Unless you are swallowing an event entirely, handler reimplementation is just to do some *additional* work. Alternately, try explicitly calling accept() in the handling code? I wish an expert might step in and educate us both. :P

qnik
8th November 2011, 15:42
Hi,
I have the sam problem with Qt 4.7.3 and Wondows 7.
I don't understand, have you solved the problem, leoalvesmachado?

leoalvesmachado
8th November 2011, 15:49
No, I didn't.
I believe it seems to be a Windows issue. Since the project I was working on was cancelled, I'm not looking for a solution to this problem anymore. I didn't test on Windows 8 though...

sl1978
20th February 2014, 09:07
Hi all,

not sure anyone resolve the issue,
I have the same issue here, and it work fine after I disable the "press and hold" feature on the windows's "Pen and Touch" setting.

hope this will help.

Rgds
SianLin