GraphicsView
Handling GraphicsView events – Part. 2
by fred on Dec.09, 2009, under GraphicsView, Qt, Widgets
In my previous post, I’ve shown you how to handle events (specifically mouse events) inside GraphicsView.
Lets expand this idea and create a customized widget on Graphics View. The simplest widget of them all is the Push Button (actually the simplest widget is the Label, but then, I wouldn’t have much to write on this post
).
The Button widget has the following characteristics:
- Display 2 images depending on its state (normal & pressed);
- Detects mouse clicks (including moving the mouse while clicked);
On to the coding part…
There’s only one attribute for storing the Button’s state: m_isPressed. Depending on the value of m_isPressed, the paint() method will either draw one of two QPixmap objects, m_normal or m_pressed.
Here’s the paint() method for the Button class:
void Button::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); if (m_isPressed) painter->drawPixmap(0, 0, m_pressed); else painter->drawPixmap(0, 0, m_normal); }
The change between the normal and pressed image happens through the mouse handling methods. Here’s the mousePressEvent() method:
void Button::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { if (contains(event->pos())) m_isPressed = true; update(); } }
If the user clicks within the image area, m_isPressed is set. Therefore, the pressed image is displayed.
Now the mouseMoveEvent() method:
void Button::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { if (contains(event->pos())) { m_isPressed = true; } else { m_isPressed = false; } update(); } }
It the user moves the mouse (while clicking) to outside the image area, m_isPressed is changed.
And finally, the mouseReleaseEvent() method:
void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_isPressed = false; update(); if (contains(event->pos())) { emit clicked(); } } }
The m_isPressed attribute is unset and the clicked() signal is emitted (if the mouse stays within the image area).
Here’s the customized Button in action:

The source code for this example is at my gitorious repository, under the button dir:
http://gitorious.org/tech-blog/sources/trees/master/button
Because the image is a rounded one, there are some parts “outside” of the Button that also receive mouse events. This happens because we still need to determine the “clickable” area through the shape() method. But that’s something for another post.
Till next time.
Handling GraphicsView events – Part. 1
by fred on Nov.16, 2009, under Git, GraphicsView, Qt
Hi, everyone. It’s been while since I’ve posted something here.
To take out some of the dust from the blog
, I figured we could start with something simple like handling events on the GraphicsView framework.
It works like this: The view (QGraphicsView) receives events and passes them to the scene (QGraphicsScene). In order to pass these events to the scene, the view must first convert these units (pixel coordinates) into scene units (vertex coordinates). This conversion process is transparent, but you access these coordinates through convenience methods like mapFromScene and mapToScene. This also applies for the inverse path (passing events from the scene to the view).
Now, let’s say you want to capture mouse events. To do that, you have to reimplement the mousePressEvent and/or mouseReleaseEvent methods. Depending on your needs, they can be reimplemented from within the QGraphicsItem class (handling single items) or the QGraphicsScene class (handling the whole scene).
Here’s an example (I’ve used the class from the previous post as reference):
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "Mouse button clicked at position: " << event->pos(); } void CustomItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "Mouse button released at position: " << event->pos(); }
Every time you click on the item, it will display a clicked message, and every time you release the mouse, it will display a released message. These methods are called whenever the desired event happens (Mouse presses, Mouse releases, Mouse moves, Key presses, Key releases, etc).
The QGraphicsSceneMouseEvent is the mouse event object. It’s a similar class to the QMouseEvent class, except that it only handles the QGraphicsView mouse events and not QWidget events.
There are also other handling methods like: mouseMoveEvent and mouseDoubleClickEvent for mouse events or keyPressEvent and keyReleaseEvent for keyboard events. For the keyboard ones, the item must be able to receive keyboard focus (QGraphicsItem::ItemIsFocusable flag set). You just need to reimplement them as in the code above.
And that’s it. I’ve also moved my previous examples (plus this one) to a repository at the Qt Gitorious.
The URL is http://gitorious.org/tech-blog/sources.
The example from this post is under the handling-events dir.