how to prevent qgraphicsitem repaint while mouse move on it
Hi,everyone. I have found a problem which troubled me for a long time:
That when i move mouse, the class which inherit from qgraphicsitem will be repainted? And this have obviously slower my graph(which drawed in the class inherits from qgraphicsItem) .
how can i prevent when the mouse move ,and the item won't be repainted?
help me soonly ! really need your help . thank you.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
christina123y
That when i move mouse, the class which inherit from qgraphicsitem will be repainted?
Yes, it might be.
Quote:
And this have obviously slower my graph(which drawed in the class inherits from qgraphicsItem) .
how can i prevent when the mouse move ,and the item won't be repainted?
There are at least three different ways to handle your situation. One possibility is to render contents of your item to a pixmap and only update the pixmap when you're not moving the item and if you are then render the old contents. Second possibility is to enable one of the caching modes for the item which does essentially more or less the same. I forgot the third solution :)
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
There are at least three different ways to handle your situation. One possibility is to render contents of your item to a pixmap and only update the pixmap when you're not moving the item and if you are then render the old contents. Second possibility is to enable one of the caching modes for the item which does essentially more or less the same. I forgot the third solution :)
I am having the same problem, that the QGraphicsItem will do unnecessary paint when the window lose/gain focus or on a mouse movement, even though there is no actual new exposure event occurring.
I think this is a bug that Qt should fix, rather than asking application developers to find a workaround...
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
lni
I am having the same problem, that the QGraphicsItem will do unnecessary paint when the window lose/gain focus or on a mouse movement, even though there is no actual new exposure event occurring.
:)
Quote:
I think this is a bug that Qt should fix, rather than asking application developers to find a workaround...
This time I won't enter this flamewar. I don't agree with you but you have the right to have a different opinion. I can only say "read the docs".
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
Yes, it might be.
There are at least three different ways to handle your situation. One possibility is to render contents of your item to a pixmap and only update the pixmap when you're not moving the item and if you are then render the old contents. Second possibility is to enable one of the caching modes for the item which does essentially more or less the same. I forgot the third solution :)
Hi, I have solved this problem through your second method.
i am very grategful for your help. But i fill confused with the first method.Can you explain for me more specifically? when the size of pixmap is in line with the size of the qgraphicsItem, while update the pixmap whether the qgraphicsItem will also being updated?
i'm looking forwad to hearing from you soonly.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
lni
I am having the same problem, that the QGraphicsItem will do unnecessary paint when the window lose/gain focus or on a mouse movement, even though there is no actual new exposure event occurring.
I think this is a bug that Qt should fix, rather than asking application developers to find a workaround...
hi, i have resolve this problem through the second method suggested by wysota. i called setCacheMode(QGraphicsItem::ItemCoordinateCache,QS ize(width(),height())) for the qgraphicsitem. you can have a try.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
christina123y
But i fill confused with the first method.Can you explain for me more specifically? when the size of pixmap is in line with the size of the qgraphicsItem, while update the pixmap whether the qgraphicsItem will also being updated?
The first method is more or less the same as the second one only that it is your responsibility to update the pixmap. The approach is described here in Qt Quarterly: http://doc.trolltech.com/qq/qq06-fli...oublebuffering
Qt3 didn't have double buffering capabilities so it had to be emulated using a pixmap.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
The first method is more or less the same as the second one only that it is your responsibility to update the pixmap. The approach is described here in Qt Quarterly:
http://doc.trolltech.com/qq/qq06-fli...oublebuffering
Qt3 didn't have double buffering capabilities so it had to be emulated using a pixmap.
I have read the reference you provide for me. and i comprehand more about the first method you suggest. and i will have a try. Thank you. any success or question will go shares.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
The first method is more or less the same as the second one only that it is your responsibility to update the pixmap. The approach is described here in Qt Quarterly:
http://doc.trolltech.com/qq/qq06-fli...oublebuffering
Qt3 didn't have double buffering capabilities so it had to be emulated using a pixmap.
Hi, i still have a question about the second method you suggested me.
i use setCacheMode() function for my item. it really didn't make my item to repaint when the mouse move on it.
Howerver when i zoom in the item , and the zoom percentage is set larger ( such as 3) or when i zoom in the graph for more times , then when the mouse move on the item, my item now begin to repaint. and i have a try ,when my zoom in percentage is 1.4*1.4, then i zoom in for two times won't make my item to repaint, when i zoom in for one more time , my item begin to repaint when the mouse move on it.
i also have set the right size of setCacheMode() when the item is scaled, this means that setCacheMode(CacheMode mode,QSize size) 's size is the same size of my item's boundingRect.
why ?
......./
and now i have found that qt has set limit to the size of cache,the default settings is 1024 kilobytes. when my graph is zoom in larger than this (1M), it now begin to call paint() to repaint.
and i also have tried to set the QSize is 1M, but it still didn't work, and this make my graph distortion. how can i resolve this problem.
wish your help soon!
I'm very appreciate for your help!
Re: how to prevent qgraphicsitem repaint while mouse move on it
Which cache mode did you use? The limit you mention is set on QPixmapCache. You can modify it using QPixmapCache::setCacheLimit().
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
i use qgraphicsitem 's cache mode ----QGraphicsItem::ItemCoordinateCache.
this method really improve speed of drawing graph.
how can i resolve the problem i encountered(don't through setCacheLimit() , any other resolvent?). how can i use QGraphicsItem::setCacheMode() and when the graph is zoom in to some extent( then when the mouse move on this item, won't make my item to repaint ), but don't through setCacheLimit() , because anyway it seems unpratical.
wish your help again!
great thanks for your help!
Re: how to prevent qgraphicsitem repaint while mouse move on it
I have trouble understanding you. What seems impractical? If you want the item to be cached you have to make sure it fits in the cache or you will either lose quality or speed. You can use the other cache mode - DeviceCoordinateCache, maybe that fits your usecase more than ItemCoordinateCache.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
I have trouble understanding you. What seems impractical? If you want the item to be cached you have to make sure it fits in the cache or you will either lose quality or speed. You can use the other cache mode - DeviceCoordinateCache, maybe that fits your usecase more than ItemCoordinateCache.
Hi, i have already tried DeviceCoordinateCache cache mode ,but it still didn't work for me.
And i have look up the other thread ---
http://www.qtcentre.org/forum/f-qtop...tes-16213.html
and i have tried setViewportUpdateMode(), still can't help for me.
and i fill puzzled with what you said on #4(Check the boundingRect() for both items. For instance using QRectF::intersects(). Just remember to map those rects to scene coordinates first. It's the bounding rects that may intersect, not the shapes themselves),
would this helpwith me?
or any other solutions to this problem? thank you
and when i zoom in the graph to some extent, the scrollbar on the qgraphicsview can be dragged very slowly., the graph is repainted , and there is serious time delay.
Re: how to prevent qgraphicsitem repaint while mouse move on it
You have to be aware you can't reduce the number of repaints to zero. Eventually your items will have to be repainted. And preventing complex repaints doesn't cause any repaints to stop - the item is still repainted but from the cache and not using complex drawing mechanisms. But if the area covered by the item becomes very big, repainting from cache might get slow as well. Tell me why exactly DeviceCoordinateCache doesn't work for you and what was wrong in using ItemCoordinateCache. Also try setting the viewport of the view to QGLWidget so that hardware acceleration kicks in.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
You have to be aware you can't reduce the number of repaints to zero. Eventually your items will have to be repainted. And preventing complex repaints doesn't cause any repaints to stop - the item is still repainted but from the cache and not using complex drawing mechanisms. But if the area covered by the item becomes very big, repainting from cache might get slow as well. Tell me why exactly DeviceCoordinateCache doesn't work for you and what was wrong in using ItemCoordinateCache. Also try setting the viewport of the view to
QGLWidget so that hardware acceleration kicks in.
First, the problem with ItemCoordinateCache mode is that --------when my item need to draw a large amount of data (such as hundreds of thousands points or millions points),this make my graph look very density, my item's boundingrect change as zoom in proportion, and i update cache with new graph(after scale), however, if i zoom in my graph to some extent(which make the size of graph is larger than the cache), then the cache's graph is unuseless , and when the mouse move on the item, the graph is repaint too slowly ,event i can't drag the scrollbar on the graphicsview.
and i can't set the size of cache absoluteness , because the data counts is uncertained (for this i also can't constraint the counts of zoom in ).
Second, i have tried DeviceCoordinateCache mode ,and the problem is the same as i use ItemCoordinateCache .
Third, i didn't catch what you say to set the viewport of the view to QGLWidget clealy.
and i know that it can't avoid repaint of item, what i need is just to enhance the speed of repaint when the mouse is move on the qgraphicsitem when the item is zoomed in to some extent.
most grateful for your reply.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
christina123y
First, the problem with ItemCoordinateCache mode is that --------when my item need to draw a large amount of data (such as hundreds of thousands points or millions points),this make my graph look very density,
This is the nature of your graph. You can modify the graph item to be composed of many smaller items each forming a cluster of points and you will immediately gain a speedup as only those clusters that are visible will be drawn.
Quote:
my item's boundingrect change as zoom in proportion,
I don't think you should change your item's bounding rect when you zoom. It's not zooming anymore if you do and Graphics View won't be able to help you much with it.
Quote:
however, if i zoom in my graph to some extent(which make the size of graph is larger than the cache), then the cache's graph is unuseless
Yes, that's why you have to increase the cache size. The item can't be redrawn out of thin air - either its verbatim copy has to be stored somewhere (like in the cache) and that uses up memory or it has to be redrawn everytime from scratch. There is no third way.
Quote:
and when the mouse move on the item, the graph is repaint too slowly ,event i can't drag the scrollbar on the graphicsview.
Again, splitting your item into smaller pieces will give you significant speedup. You can also disable interactivity of the view by calling QGraphicsView::setInteractive(false) which should prevent your items from being repainted as a reaction to mouse events.
Quote:
and i can't set the size of cache absoluteness , because the data counts is uncertained (for this i also can't constraint the counts of zoom in ).
I don't know how would you expect it to work then :) There is no "infinity" in computer language. The amount of memory is limited and once you go over the edge your application will start acting abnormally.
Quote:
Third, i didn't catch what you say to set the viewport of the view to QGLWidget clealy.
Quote:
and i know that it can't avoid repaint of item, what i need is just to enhance the speed of repaint when the mouse is move on the qgraphicsitem when the item is zoomed in to some extent.
Split the item. You can control the extent of splitting by setting a minimum/maximum number of points per cluster. If you have a single item that is larger than the area of the viewport you can see in the view then the item has to be redrawn completely anyway - including all the points in the graph. Now if you split the graph into many items, only those clusters of points that are visible will have to be redrawn. This is a speedup you get practically for free, without any caching or anything. It's worth a shot.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
This is the nature of your graph. You can modify the graph item to be composed of many smaller items each forming a cluster of points and you will immediately gain a speedup as only those clusters that are visible will be drawn.
Again, splitting your item into smaller pieces will give you significant speedup. You can also disable interactivity of the view by calling
QGraphicsView::setInteractive(false) which should prevent your items from being repainted as a reaction to mouse events.
Split the item. You can control the extent of splitting by setting a minimum/maximum number of points per cluster. If you have a single item that is larger than the area of the viewport you can see in the view then the item has to be redrawn completely anyway - including all the points in the graph. Now if you split the graph into many items, only those clusters of points that are visible will have to be redrawn. This is a speedup you get practically for free, without any caching or anything. It's worth a shot.
hi, extremely grateful for your so good suggestion. Originally, my design to draw all points in an item in view of it will be easy to operate. and if i splitter all the points to several items, i don't know how to put these items together!
now,according to your direction, my thought is : splitter QVector<QPointF> vector which stores all the points to several segment, and then draw each segment's points on an item, but how can i put these items together appropriately just to compose integrate and correct graph, this means how i know where to put these small items, and how can i map each segment points to corresponding item's coordinate.
And here is another question ,because when my application first start ,the whole graph is shown, and i splitter it to several items , when i zoom in , the graph is scaled, and how can i determin which items should be repainted(even i don't know after zooming in, which of these small items will be in the visible area), and if some points of a small item are in the visible area, other are not, then repaint? and if i zoom in the graph ,the items which are in the visible area , whether their boundingrect change as the zoom in proportions, or just use the QGraphicsItem::scale() to achieve this.
wish i has expressed clearly .
and looking forward to your reply again.
best appreciated to you.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
christina123y
Originally, my design to draw all points in an item in view of it will be easy to operate. and if i splitter all the points to several items, i don't know how to put these items together!
I'm not sure what you mean by putting them together. You can have an item that represents the background of the graph (axis, etc.) and have multiple items that are child items of the graph item representing the contents of the graph (points).
Quote:
now,according to your direction, my thought is : splitter QVector<QPointF> vector which stores all the points to several segment, and then draw each segment's points on an item, but how can i put these items together appropriately just to compose integrate and correct graph, this means how i know where to put these small items, and how can i map each segment points to corresponding item's coordinate.
For splitting space usually an algorithm called BSP (binary space partitioning) is used. It splits the plane into two sub-planes and then splits each sub-plane again and again until it reaches the stop condition. GraphicsView uses that algorithm internally to quickly find items based on their geometry. If you decided to represent each point in the graph as separate item, you could automatically use that built-in mechanism but if you want to have clusters, you have to implement BSP yourself.
Quote:
and how can i determin which items should be repainted
Qt does that for you. It will only repaint items that need repainting (i.e. those that are visible and have been marked as dirty).
A rule of a thumb is that if you have one item in the scene - you probably shouldn't be using QGraphicsView at all as it only adds to the complexity giving nothing in exchange. If you want to use Graphics View, have multiple items. Group them as you want using the parent-child relationship and squeeze as much from the architecture as possible.
If you only want a single item with zooming and scrolling, you'll get much better results with a custom widget derived from QAbstractScrollArea.
Re: how to prevent qgraphicsitem repaint while mouse move on it
Quote:
Originally Posted by
wysota
I'm not sure what you mean by putting them together. You can have an item that represents the background of the graph (axis, etc.) and have multiple items that are child items of the graph item representing the contents of the graph (points).
today i have tried that each point as a child qgraphicsitem, and set a coordinate item as their parent, and it did draw correct graph. but, my points is larger then 12,0000
(they are float type ) ,i found ithat when i zoom in the graph to some extents it become slowly again,fairly slowly ,even make my application dead.
Quote:
Originally Posted by
wysota
For splitting space usually an algorithm called BSP (binary space partitioning) is used. It splits the plane into two sub-planes and then splits each sub-plane again and again until it reaches the stop condition. GraphicsView uses that algorithm internally to quickly find items based on their geometry.
i have look up the reference of BSP , but it is still obscure to me.maybe i should spend some time to investigate this. would you please provide me some relative reference? thank you.
Quote:
Originally Posted by
wysota
If you decided to represent each point in the graph as separate item, you could automatically use that built-in mechanism but if you want to have clusters, you have to implement BSP yourself.
what do you mean "automatically use that built-in mechanism "? i make each point as a separate item, and then use QGraphicsItem::setPos() in its parent item. how should i use
alleged built-in mechanism ? Or Qt does that itself? but why didn't this way improve the speed. and it still repaint very slowly.
Quote:
Originally Posted by
wysota
A rule of a thumb is that if you have one item in the scene - you probably shouldn't be using QGraphicsView at all as it only adds to the complexity giving nothing in exchange. If you want to use Graphics View, have multiple items. Group them as you want using the parent-child relationship and squeeze as much from the architecture as possible.
If you only want a single item with zooming and scrolling, you'll get much better results with a custom widget derived from
QAbstractScrollArea.
i use QGraphicsView for i need to make my application perform other functions such as mouse tracker, and so on. next time i will think over what frame or just qwidget to use.and with great thanks to your advice.and how to use BSP to achieve improving speed of repaint?
best wishes to you!
Re: how to prevent qgraphicsitem repaint while mouse move on it
I think you might take a closer look into "40000 chips" demo from Qt, but I'm not sure that it's what you want: http://doc.trolltech.com/4.5/demos-chip.html