PDA

View Full Version : Mouse press event in a QGraphicsScene



Lykurg
18th June 2009, 17:42
Hi,
an old problem is bothering me and I can't get it fixed. After double clicking a custom QGraphicsTextItem, I want to move the cursor of the QTextDocument to the position under the cursor. This is the behavior you can achieve if you press three times the mouse button. So I thought just send a mouse event, but I fail. Here my files:


#include <QtGui>
#include "myitem.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

MyItem *it = new MyItem();
it->setPlainText("String to edit");

QGraphicsScene scene;
scene.addItem(it);

QGraphicsView view(&scene);
view.show();

return a.exec();
}

#ifndef MYITEM_H
#define MYITEM_H

#include <QtGui>

class MyItem : public QGraphicsTextItem
{
Q_OBJECT

public:
MyItem(QGraphicsItem *parent = 0);
QMouseEvent *e;

protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void focusOutEvent(QFocusEvent *event);
};

#endif /* MYITEM_H */

#include "myitem.h"

MyItem::MyItem(QGraphicsItem *parent)
: QGraphicsTextItem(parent)
{
setTextInteractionFlags(Qt::LinksAccessibleByMouse );
}

void MyItem::mouseDoubleClickEvent(QGraphicsSceneMouseE vent *event)
{
if (textInteractionFlags() & Qt::TextEditorInteraction)
{
QGraphicsTextItem::mouseDoubleClickEvent(event);
}
else
{
setTextInteractionFlags(Qt::TextEditorInteraction) ;
// HERE SOME MAGIC CODE TO MOVE THE CURSOR
// which is by default at 0 after calling setTextInteractionFlags(Qt::TextEditorInteraction) .
}
}

void MyItem::focusOutEvent(QFocusEvent *event)
{
setTextInteractionFlags(Qt::LinksAccessibleByMouse );
QGraphicsTextItem::focusOutEvent(event);
}


I need to set the editor functionability only after a double click. All attempts to redirect the event leads in a total selection of the text. And creating different QMouseEvents and send them via QCoreApplication::sendEvent ended somewhere in Nirvana...

Any hints are welcome. Even code, as you know I am to lazy to do the work by my own, and it's your job to do my work...:D

Thanks,

Lykurg

shentian
18th June 2009, 19:29
Hi,
my idea was to directly call QGraphicsItem::mousePressEvent. For this, you need to create a QGraphicsSceneMouseEvent. According to the Qt API Docs, there seems to be no way, but after a peek into the source code of QGraphicsScene, I came up with the following:


void MyItem::mouseDoubleClickEvent(QGraphicsSceneMouseE vent *event)
{
if (textInteractionFlags() & Qt::TextEditorInteraction)
{
QGraphicsTextItem::mouseDoubleClickEvent(event);
}
else
{
setTextInteractionFlags(Qt::TextEditorInteraction) ;
// HERE SOME MAGIC CODE TO MOVE THE CURSOR
QGraphicsSceneMouseEvent newEvent(QEvent::GraphicsSceneMousePress);
newEvent.setScenePos(event->scenePos());
newEvent.setPos(event->pos());
newEvent.setButtons(event->buttons());
newEvent.setButton(event->button());
newEvent.setModifiers(event->modifiers());
QGraphicsTextItem::mousePressEvent(&newEvent);
}
}

It's a bit nasty, since it uses non-API public members of QGraphicsSceneMouseEvent (marked as 'internal'), but it works... ;)

Lykurg
19th June 2009, 08:22
It's a bit nasty, since it uses non-API public members of QGraphicsSceneMouseEvent (marked as 'internal'),
I intended to avoid use internal stuff...

but it works... ;)
...yeah, what the heck, what works works, I will use that. By the way I also guess that they wont change so much on that.
Thanks very much, that you have spend your time looking through the sources, to get a solution for my problem, I appreciate that!

But I am still confused why something link that don't work:

QMouseEvent ne(QEvent::MouseButtonPress, event->pos().toPoint(), event->button(), event->buttons(), event->modifiers());
QApplication::sendEvent(this, &ne);

The event is delivered to MyItem, says my eventFilter, but the reimp MyItem::mousePressEvent() isn't invoked. Also used QCursor:: pos(), Qt::LeftButton...


Lykurg

shentian
19th June 2009, 11:28
MyItem::mousePressEvent() isn't invoked because you are sending a QMouseEvent, not a QGraphicsSceneMouseEvent. And sadly, API doesn't allow to create a QGraphicsSceneMouseEvent :(

Maybe you can try to send a QMouseEvent to the QGraphicsView, which will translate it to a QGraphicsSceneMouseEvent.

I tried this, but it doesn't seem to work either:


QGraphicsView* view = scene()->views().first();
QMouseEvent ne(QEvent::MouseButtonPress, view->mapFromGlobal(event->screenPos()), event->button(), event->buttons(), event->modifiers());
QApplication::sendEvent(view, ne);