PDA

View Full Version : problem with QPixmap::grabWidget()



momesana
18th October 2007, 05:14
I am trying to implement a sort of a ThumbnailView for arbitrary widgets like QTabWidget. Now, if I try to grab a Pixmap from a widget that has not been shown so far (like a tab), this results in a wierd pixmap being returned by QPixmap::grabWidget(). If the Widget was displayed once, however, the method returns a proper pixmap. This is probably caused by the fact that no paintEvent has been triggered for the Widgets in question but I am not sure.

Is there a way to work around this? I have included a compilable app highlighting the problem. In thumbnailmode you can doubleclick the items to let them take a new pixmap. Do this for tabs that were displayed and compare with those not displayed yet (i.e. tabs whose associated widget were not shown yet).

Unfortunately the example code became too large (~270 lines) and too ugly which defeats the purpose of being minimal and thus is not very easy to comprehend. I have attached it to this post nonetheless.

Thanx in advance

1656

kernel_panic
18th October 2007, 08:10
i changed grabWidget into m_widget->render(); and i go through all tabwidgets at beginning, to update them.

momesana
18th October 2007, 09:06
The trick also works with grabWidget. The decisive parts are the QTimer::singleShot() and activating the current tab before grabbing the widget in the Items constructor. What I do not fully understand is what the QTimer is contributing to this effect and why it does not work without it. I have attached my current version based on your modifications.

1658

kernel_panic
18th October 2007, 09:11
The timer because i want to wait until the widget is created (with right sizes etc). 1ms is enough for this.
and i declared createTabWidgets as a slot and a slot cant be called in the constructor. why ever...

momesana
18th October 2007, 09:36
I still wonder why the widget must be activated first. The grabWidget memberfunction documentation says this:



This function actually asks widget to paint itself (and its children to paint themselves) by calling paintEvent() with painter redirection turned on.


So, I don't know why on earth the widget must be shown first to get the pixmap right. maybe the paintEvent is not directly executed but rather scheduled to be processed just before the widget is shown. But that also doesn't make sense, since I've tested that with changing widgets (Webkits QWebPage) while in thumbnailmode and the thumbnails correctly reflected the changes (load status) of the QWebPage.

kernel_panic
18th October 2007, 10:42
i think its qtabwidget. if you render or grab any widget which isnt in a tabwidget, it works fine.
i dont use tabwidget very often because its very buggy (if you apply an scrollarea to a child the child is taken away from tabwidget eg). maybe this is a bug, too.

jpn
19th October 2007, 01:57
So, I don't know why on earth the widget must be shown first to get the pixmap right. maybe the paintEvent is not directly executed but rather scheduled to be processed just before the widget is shown.
Geometry of a widget is calculated by the time it's shown for the first time. Until that, geometry is undefined unless one explicitly sets it.


i dont use tabwidget very often because its very buggy (if you apply an scrollarea to a child the child is taken away from tabwidget eg).
It would be interesting to see a clear and minimalistic sample code which illustrates this problem.