PDA

View Full Version : Adding Rectangular overlay on graphics view



forrestfsu
17th November 2006, 15:36
To simplify my problem, lets assume that we have two different graphics views. Both of these views have the same scene applied to it. When the user clicks on a specific point in the first graphics view I want to draw a rectangle related to the point she clicked, but I want it to only be visible in that graphics view. So I'm assuming I can't just add a rectangle to the scene because it would be visible on both. I was looking into using QGraphicsView's foregroundBrush(), but I'm not sure if that is what I'm looking for either. Doesn't the foregroundBrush tile the brushes pixmap? Any ideas would be appreciated.

spud
17th November 2006, 15:55
You probably want to override QGraphicsView::drawForeground().

forrestfsu
20th November 2006, 14:53
I'm having problems writing the code to override drawForeground (or any virtual protected function for that matter). Does anyone know if there is an example I can look at? I'm trying to go through the message boards but no luck so far.

thanks for the tip spud...

jpn
20th November 2006, 15:41
Here's a little example how to override QGraphicsView::drawForeground():

Class declaration:


class MyGraphicsView : public QGraphicsView
{
public:
MyGraphicsView(QWidget* parent = 0);
...

protected:
void drawForeground(QPainter* painter, const QRectF& rect);
};


Implementation:


void MyGraphicsView::drawForeground(QPainter* painter, const QRectF& rect)
{
painter->drawRect(...);
}

forrestfsu
20th November 2006, 16:04
thanks j-p,

I'm not seeing anything in the graphicsview's with:


void myForm::drawForeground(QPainter *painter, const QRectF &rect)
{
QPen border(QColor(200,100,40));
painter->setPen(border);
painter->drawRect(10,10,100,300);
}

It compiles, but I'm not seeing any rectangle being drawn. The other thing I'm worried about is that I currently have more then 1 graphics view in this class. I only want this drawForeground function to run for one of them, is that do-able? Also, is there a way to call this function whenever I need the rectangle to be updated?

Bitto
20th November 2006, 23:05
Both QGraphicsView and QGraphicsScene define a virtual drawForeground() function. If you reimplement the one in the scene, all views will see this foreground, but you can just reimplement it in a view to create a view-specific foreground.

These functions draw in scene coordinates, so you just need to make sure that what you are drawing fits inside the scene rect. If your scene rect (see QGraphicsScene::sceneRect()) is defined as (-1000, -1000, 2000, 2000), you could do this to draw a transparent green overlay:


void MyScene::drawForeground(QPainter *painter, const QRectF &exposed)
{
// 50% transparent green overlay
painter->fillRect(-1000, -1000, 2000, 2000, QColor(0, 255, 0, 127));
// or
painter->fillRect(exposed, QColor(0, 255, 0, 127));
}


The exposed argument is an optimization for partial updates; you don't want to fill the whole scene it only parts of it are exposed.

forrestfsu
21st November 2006, 14:10
How exactly am I supposed to call this function for a particular graphicsView? Is there a specific QPainter pointer that I need to pass as a parameter that is related to the specific graphicsView? I'm just unclear as to how and when this drawForeground function is being called.

aamer4yu
21st November 2006, 14:56
u need not call this function... it is called automatically.
U just need to override it in ur scene class and do the drawing using the painter pointer provided :)

forrestfsu
21st November 2006, 16:06
I think I'm beginning to understand what you've all been talking about. But the QGraphicsView's that I'm using were all added to the same widget using Qt Designer. Am I supposed to write a class for each graphicsView that I added in designer? If so, how can I write a class for each individual graphicsView? Or am I still way of target?

jpn
21st November 2006, 16:19
Qt Designer has a widget promotion (http://doc.trolltech.com/4.2/designer-using-custom-widgets.html#promoting-widgets) feature. Subclass QGraphicsView, open context menu over the graphics view widget in the designer and choose "Promote to Custom Widget".

forrestfsu
21st November 2006, 19:42
Thanks everyone! I got it working using a variety of all your tips. Mainly I used the widget promotion in designer, and then subclassed QGraphicsView to do what I wanted. :)