PDA

View Full Version : implementing drawForeGround



Wirloff
5th April 2007, 14:31
Hi,
I'm quite new to Qt. I have a problem with drawing on a QGraphicsView. I have added a working example in the zip file:

I create a MainWindow app in Designer, and add a GraphicsView to it. In the code from MainWindow.cpp I create a QGraphicsscene, draw 256 little green rectangles on it (the rectangles are an instance from my own made class Graphics, which implements QGraphicItem), and let the GraphicsViewer select the scene. And this all works fine.

But now I want to change the color of a rectangle when clicked on it. I know that I have to use te mousepressedEvent (propably in the Graphics class), and that I maybe should use the drawForeGround methode. But I don't really get how that works Anyone who can help me, and help me on the right way?

Thanx in advance,
Wirloff

wysota
5th April 2007, 19:52
You don't need to use drawForeground. You only need to reimplement the paint() method of your item class (which you probably already did) and mouse press event to modify the item when it's clicked.

Wirloff
10th April 2007, 07:42
I'm afraid I don't really get it. This is my GraphicsItem code:


#include <QtGui>
#include <QPainter>
#include <iostream>

#include "Graphics.hpp"

Graphics::Graphics(): color(qrand() % 256, qrand() % 256, qrand() % 256)
{
setCursor(Qt::OpenHandCursor);
}

QRectF Graphics::boundingRect() const
{
return QRectF(0, 0, 25, 25);
}

void Graphics::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::green);
painter->drawRect(0, 0, 10, 20);

}

void Graphics::mousePressEvent(QGraphicsSceneMouseEvent *event)
{


}

I have read that there is no such thing as a "repaint"-method. So know I'm wondering how to call a kind of repaint from in mousePressEvent??

guilugi
10th April 2007, 09:38
As I said in your other thread, you have the update() method, that will just call paint ! :)

elsheikhmh
10th April 2007, 11:56
if you want to change the color of the item upon selection then restore the color again upon de-selection:
Set ItemIsSelectable flag in Graphics::Graphics()


setFlag(ItemIsSelectable);

then in Graphics::paint() change the color of the brush if the item is selected


if (isSelected())
painter->setBrush(Qt::black);
else
painter->setBrush(Qt::green);


if you want to change the color of the item upon selection forever:
no flags, just reimplement mousePressEvent()


void Graphics::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (brushcolor == Qt::green)
brushcolor = Qt::black;
update();
QGraphicsItem::mousePressEvent(event);
}

then your Graphics::paint() should set the brush color:


painter->setBrush(brushcolor);

and in your constructor:


brushcolor = Qt::green;

also, don't forget to define brushcolor as member of Graphics class:


private:
...
Qt::GlobalColor brushcolor;

i tried both, and they worked fine with me. except the second method, two items are selected at a time. i think you have something strange in your bounding rect or i did something wrong.

Regards,
-Mustafa

Wirloff
10th April 2007, 12:49
Thanx, I have got I working :) I understand everything now, except one thing: what does the next sentence do:


QGraphicsItem::mousePressEvent(event); //in the paint method

Thanx again to all of you

guilugi
10th April 2007, 13:02
This sentence calls the default implementation of this method.
Really useful, you don't have to handle all the possible events : just reimplement the one you are interested in, and let the default code handle the others ;-)

Wirloff
11th April 2007, 09:03
Everything works very fine but now I have another (new) problem:

When clicked on a rectangle, the main program should be able to know where there has been clicked. Is it possible to send a signal to the Scene from within eg: Item's mouseEvent???

guilugi
11th April 2007, 09:38
Well, items are not QObject, so you can't use signals / slots, unless you made a subclass which inherit QObject :)

You can always have access to the scene pointer with scene() (only if you stored your item in the scene).

QGraphicsMouseEvent has useful methods to obtain position : pos() -> item coordinates, scenePos() -> scene coordinates.

wysota
11th April 2007, 16:03
If an item ignores an event, it will propagate to the scene and can be handled there. I don't know if it is exactly what you want... Maybe it'll be easier to call some method of the scene in item's mouse event handler instead?