How do I find out which widgets/canvas items are visible?
Hi,
I need to find out which parts of which widgets are actually being shown. Usually the system will post a paint event when a widget needs to be redrawn, however, I have changing data which I want to display dynamically. The computation of the data is expensive and if the widget (canvasview) is obscured but other windows. The isVisible property is not sufficient since it is true even if the view is obscured. Ideally I would like to know which canvas items are visible and even parts that are visible. I don't know if I can reuse the paint engine for this since that must figure out which parts need to be redrawn. It seems like the draw() method is called every time I call an upate() on the canvasitem regardless if the item is actually visible or not. I know that the paint engine knows if an item is visible or not since no draw() method is called when the item is obscured and I move a window over it.
I would like to avoid the costly preparation of my data if it can't be seen anyway.
Any ideas how to handle this?
Thanks,
Tom
Re: How do I find out which widgets/canvas items are visible?
In the paint event you have all the information you need.
Quote:
const QRect & QPaintEvent::rect () const
Returns the rectangle that should be updated.
See also region() and QPainter::setClipRect().
Examples: life/life.cpp, qfd/fontdisplayer.cpp, showimg/showimg.cpp, t10/cannon.cpp, t11/cannon.cpp, t13/cannon.cpp, and tooltip/tooltip.cpp.
const QRegion & QPaintEvent::region () const
Returns the region that should be updated.
See also rect() and QPainter::setClipRegion().
Examples: qfd/fontdisplayer.cpp and scribble/scribble.cpp.
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by Tommytrojan
Any ideas how to handle this?
Maybe you could deduce whether the item is visible from the region returned by QPainter::clipRegion()? Although it might not work for every update.
Re: How do I find out which widgets/canvas items are visible?
Thanks for the quick answers.
The problem is that the update() call on the canvas item causes the canvas to repaint all views that have that item set to visible. So as long as I call update() the paint even will include all these items to be updated, which is perfectly fine. However, I call update() on any data event my system delivers (think of it as a stock ticker). Now, if the canvas item is obscured it still gets the paint event (actually a draw() for the canvasitem). So I guess what I need is a function that tells me if a particular canvas item is obscured and therefore I don't even need to call update(). I can do this in a limited fashion for windows that are iconized since I know that the canvas view won't be able to show these items but if the user keeps all the windows open (and they could have hundreds of windows) I have no idea which ones are actually visible.
How does Qt know which widgets and canvas items to repaint? It must have a notion of 'visible' widgets/items.
Thanks,
Tom
Re: How do I find out which widgets/canvas items are visible?
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by Tommytrojan
However, I call update() on any data event my system delivers (think of it as a stock ticker).
Which update() do you call?
Re: How do I find out which widgets/canvas items are visible?
Axel,
that doesn't solve the problem. I need to know 'before' I call the update() of my canvasitem if the item would be in the paint region, once I get the paint() event it is too late since I have to provide the data by then.
I have to call update() once my system has new data available, however, I DON'T want to call update() if the item is obscured and won't be seen. Once I call update() the entire item (QCanvasItem) will be in the paint region anyway, so the decision to call update has to be made prior to the paint event (which hopefully never happens if the item is obscured to begin with). I hope I stated the problem correctly.
Thanks,
Tom
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by jacek
Which update() do you call?
Jacek,
I call QCanvasItem.update(). Well, it is a subclass where I implement the drawing of the item. Whenever a data even occurs in my system I have to go through a lengthy formatting procedure and prepare the output, then I call update() to get the data rendered. I would like to not have to go through the formatting if the item is not being displayed anyway. So what I want is:
Code:
fOnData(char* szData)
{
if !isObscured()
{
fFormatData(szData);
update();
}
// Ignore data as it is not rendered anyway
else
{
}
}
If the items gets uncovered and a paint even issued I can recover the data and do the formatting then. The data events occur with a 100ms frequency and there can be thousands of them, so it is important to not incur this overhead until it is really needed.
Thanks,
Tom
Re: How do I find out which widgets/canvas items are visible?
Maybe QCanvas::setChanged() helps you? If you look at its source code, you'll notice how the canvas stores its changed regions. While an update() is issued, it checks which regions of the canvas need updating and updates only those parts of the sheet.
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by Tommytrojan
I call QCanvasItem.update(). Well, it is a subclass where I implement the drawing of the item. Whenever a data even occurs in my system I have to go through a lengthy formatting procedure and prepare the output, then I call update() to get the data rendered.
QCanvasItem::update() only marks canvas chunks as modified. IMO it shouldn't trigger any repainting (the docs say something different, so I might have missed something when I was reading the sources).
BTW. You can try tuning the QCanvas chunk size. Also make sure that your item reports proper bounding rectangle.
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by jacek
QCanvasItem::update() only marks canvas chunks as modified. IMO it shouldn't trigger any repainting (the docs say something different, so I might have missed something when I was reading the sources).
BTW. You can try tuning the QCanvas chunk size. Also make sure that your item reports proper bounding rectangle.
Well, the item gets updated properly, so I assume that the bounding rectangle and everything else is okay. The problem is that it does get updated every time! I would like it to invoke my draw() function only when it actually is visible. However, I calls my draw() function even when it is obscured...
T
1 Attachment(s)
Re: How do I find out which widgets/canvas items are visible?
Quote:
Originally Posted by Tommytrojan
Well, the item gets updated properly, so I assume that the bounding rectangle and everything else is okay.
Yes, but the bigger bounding rectangle is, the more likely update is to occur.
Quote:
Originally Posted by Tommytrojan
The problem is that it does get updated every time! [...]However, I calls my draw() function even when it is obscured...
It looks like Qt doesn't know that a part of a window is hidden under another one.
In case somebody wants to research this subject further, I've attached a little program I wrote to test few ideas.