PDA

View Full Version : Slow Movement of QGraphicsItem



Raghaw
19th September 2012, 07:37
Hi All,

I have one big performance problem in my App which i am not able to figure out.I have one Image which is basically QGraphicsPixmapItem and that iam resizing it to make it appear on my small screen meant to display images.Its resolution is SXGA(1280*1024) and When iam drawing some QGraphicsItem lets say an Rectangle and try to drag it its movement is very slow.

I have tried all the flags settings.But thats not helping me out.Is there some rendering tips which i need to keep in mind while drawing a QGraphicsItem.

Please help me out.

ChrisW67
19th September 2012, 07:47
Without seeing a small example that shows us exactly what you are doing, and how the image and the rectangle are related to each other, we can only guess.

Raghaw
19th September 2012, 08:25
Without seeing a small example that shows us exactly what you are doing, and how the image and the rectangle are related to each other, we can only guess.



//This CImageWidgetOverlay is derived from QGraphicsItem
void CImageWidgetOverlay::paint(QPainter * p, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
if (this->isActive() && m_ShowOverlay)
{
if(m_ROIsList && !m_ROIsList->isEmpty())
{
for(int i = 0; i < m_ROIsList->count(); i++)
{
if (m_DisplayOverlayMask && (!m_OverlayMaskImage.isNull()) && (m_ROIsList->at(i)->getShape() == FA5_SHAPE_RECT_MASK))
{

double fScale = m_ROIsList->at(i)->getCurrentScale();
QRectF rect = QRectF(m_OverlayOffsetCol * fScale, m_OverlayOffsetRow * fScale, m_OverlayMaskImage.width() * fScale,
m_OverlayMaskImage.height() * fScale);
p->drawImage(rect , m_OverlayMaskImage, m_OverlayMaskImage.rect());


}
m_ROIsList->at(i)->drawROI(p);
}
QRectF roiBoundary = m_ROIsList->at(0)->mappedRect();
m_ResultBar->move(roiBoundary.right() + 10, roiBoundary.bottom() - m_ResultBar->rect().height());
m_ResultBar->drawResultBar(p);
}
}
}




void CGraphicsScene::initImage(QImage* image)
{
m_CurrentImage = image;
if(m_CurrentImage)
{
m_Resolution = CResolution::getResolutionID(m_CurrentImage->size());
}
setDefaultImage(m_CurrentImage);
update(this->sceneRect());
}

void CGraphicsScene::setDefaultImage(QImage* image)
{
m_widgetPixmap->setPixmap(QPixmap::fromImage(*image));
setSceneRect(image->rect());
}

ChrisW67
19th September 2012, 08:44
You are resizing a number of images every time you go through the paintEvent(), which happens a lot when dragging even though the image is not changing size. You should consider rendering the images into a QPixmap only when they are resized (or changed) and use a QPixmapCache.

Raghaw
19th September 2012, 09:55
Thanks Chris for ur reply .Can you be more specific by second line ...??

d_stranz
19th September 2012, 17:28
Can you be more specific by second line ...??

Look at the QGraphicsItem::setCacheMode() flags. Use QGraphicsItem::DeviceCoordinateCache. If you set this flag in the constructor of your class, then the paint() method will be called only when the items changes size. Otherwise, it will always be redrawn using the behind-the-scenes pixmap cache.

(Don't know what's up with the "QTCLASS" tags today - they are now all showing up as links to the Digia.com site, and all of them are giving me a 404 error, even this link to QWidget).

Raghaw
21st September 2012, 08:04
d_stranz i Have tried this flag also but the result is same.No change....Okie i will try to elaborate my problem..

We are actually using one image which continuously comes from a camera
onto a QGraphicsPixmapItem.This QGraphicsPixmapItem i am adding to
QGraphicsScene.Then we are resizing this image widget into which we are
displaying this camera image with aspect ratio 4:3.The Resolution of the
image is SXGA.
Then we are drawing different shapes (Region of interest) on top of this
image. If we try to drag these shapes the dragging is not smooth.We have
other resolutions like VGA, QVGA etc.Dragging is somewhat smooth on
these smaller resolutions.

d_stranz
22nd September 2012, 17:15
So you mean you are trying to move a rectangle (ROI) that is a child of the QGraphicsPixmapItem that contains the image that is simultaneously being downloaded from a camera, resized to fit the pixel dimensions of the view, and then updated on screen?

Any user interaction with the ROI is going to be very slow with respect to the refresh rate of the camera image, and every movement of the ROI is going to cause an update on the image, so it sounds to me like you are getting double updates every time the ROI is moved.

I would try separating your GUI into two different widgets: the graphics view that contains the image, and an overlay widget (with a transparent background) that contains another graphics view of the same dimensions and sits exactly on top of the image view. You use this view to display and interact with the ROI items.

You could also try freezing updates (or greatly reducing the frequency) of the image when an ROI move is in progress.

wysota
22nd September 2012, 17:35
I would even say that every move is going to cause a rescale and an update as I'm assuming it is the item that is being scaled and not the image prior to attaching it to the item. Since the image is constantly changing, caching indeed will not help much.

Raghaw
24th September 2012, 07:15
Dear D_Stranz,
Rectangle is not child of QGraphicsPixmapItem .This Rectangle and Image from camera(Which is i am drawing on QGraphicsPixmapItem) are childs of QGraphicsScene.

d_stranz
24th September 2012, 18:55
Rectangle is not child of QGraphicsPixmapItem .This Rectangle and Image from camera(Which is i am drawing on QGraphicsPixmapItem) are childs of QGraphicsScene.

It still doesn't matter. If you move the rectangle over the pixmap, it will force the pixmap to redraw as different areas are exposed. And if in the process of redrawing the pixmap you are also rescaling it from the camera image, that is a huge amount of work to do every few ms and it gets worse as the number of pixels (size of the pixmap) increases. Try what I suggested: use an overlay widget to draw the ROI so your ROI is not in the same scene (or even in the same graphics view) as the pixmap.

I would probably not even bother with the G-V architecture for the pixmap part at all - if the pixmap occupies the entire window, then just use a QWidget-based view to display it, and use the G-V architecture in the overlay widget only. If the scene coordinates match the pixmap dimensions, then all the coordinates will be self-consistent.

Raghaw
25th September 2012, 10:30
It still doesn't matter. If you move the rectangle over the pixmap, it will force the pixmap to redraw as different areas are exposed. And if in the process of redrawing the pixmap you are also rescaling it from the camera image, that is a huge amount of work to do every few ms and it gets worse as the number of pixels (size of the pixmap) increases. Try what I suggested: use an overlay widget to draw the ROI so your ROI is not in the same scene (or even in the same graphics view) as the pixmap.

I would probably not even bother with the G-V architecture for the pixmap part at all - if the pixmap occupies the entire window, then just use a QWidget-based view to display it, and use the G-V architecture in the overlay widget only. If the scene coordinates match the pixmap dimensions, then all the coordinates will be self-consistent.

I tried ur solution but its not solving the issue...Iam attaching the zipped files