Question

I'm trying to make a function similar to impoly (from matlab) in Qt. Right now, I have a subclass of QGraphicsView and have set the virtual function "drawBackground" as:

void roiwindow::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->save();
painter->drawImage(rect, *refimage);
painter->restore();
}

This works great and is basically exactly what I want as far as the background layer. Now, I'm trying to add circles that will eventually act as nodes for the polygon. I did this by using:

QGraphicsView *view = new QGraphicsView(this);
view->show();
QGraphicsEllipseItem *e1;
e1 = this->addEllipse(20, 20, 30, 30, QColor(0, 0, 0), Qt::white);
e1->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsMovable);

This is sort of what I want. But, there is a problem that when I click and drag the ellipses, the background of the ellipse is a scaled down version of *refimage... This leaves sort of a streak across the screen but it disappears when I click on another window or minimize the window. Does QGraphicsItem also call drawBackground? If so it seems to only call it when the item is being dragged. Any suggestions for how I can code this better? Thanks.

Was it helpful?

Solution

The streaks are occurring because you probably have QGraphicsView set to the default viewport update mode, which is QGraphicsView::MinimalViewportUpdate. In this case, you need QGraphicsView::FullViewportUpdate. The reason is that when you move items around, the background behind them needs to be redrawn, but when you have MinimalViewportUpdate set, only the items will be redrawn (unless there is a full viewport update, e.g., from minimizing/maximizing the window).

OTHER TIPS

QGraphicsView::drawBackground is called whenever something of the graphics view needs to be redrawn. This something might be smaller than the whole view for a better performance.

Example: When you have a rectangular item, let's say 50 x 50 pixels, within a bigger scene / view and you move this rectangle by 20 pixels to the right, only the region covered by the previous + new position of the item (70 x 50 pixels) gets redrawn (as this is the region which changes).

In your reimplementation of drawBackground, you say:

painter->drawImage(rect, *refimage);

which actually draws the image at and in the size of the region to be updated, not the total size of the view.

In order to draw the image every time at the same position and in the same size, you could use a constant position (e.g. the origin) and don't change the size of the image:

painter->drawImage(0, 0, *refimage);

or you could use the scene's whole region:

painter->drawImage(sceneRect(), *refimage);

where sceneRect() is defined as the same rect your scene uses for the whole scene. This rect is updated automatically when you add new content which would be out of the rect. You can also force a scene rect by setting it manually to a value, for example:

scene()->setSceneRect(0, 0, 800, 800);

See documentation: QGraphicsView::sceneRect and QGraphicsScene::sceneRect

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top