PDA

View Full Version : grabeWidget & QTabWidget problem



conglu
20th April 2007, 17:03
Hello, guys,

Very glad to be here. This is my first post.

I recently have a problem with saving my application interface (some X-Y charts) to PNG files using QPixmap::grabWidget and QTabWidget. My chart is drawn on a QwtPlot object in the pages of a QTabWidget object. And I have 9 pages totally. I want each single page be saved automatically to a PNG file for later review (no button press, mouse click etc.). The files are saved, but some components of the chart are missing (looks like the chart is not done yet, so I put Sleep(500) in there). I tried grabWindow(), but since the pages of the QTabWidget are not visible at this moment of time, so I can not get what I want. I am using QT 3.3.6 and Qwt 4.2 and MSVS 2005.

I attach some of my codes, hope someone can help me out. Thanks in advance.

for(int i = 8; i>=0; i--)
{
s_tab_view->setCurrentPage(i); // s_tab_view: QTabView
QPixmap peakPixmap;
QString pixMapFileName = "C:\\pinPostDoc\\" + dateQString + "_" +
s_tab_view->label(i).remove('&') + ".png";
Sleep(500);
peakPixmap = QPixmap::grabWidget(s_tab_view, 0, 0, -1, -1);
beakPixmap.save(pixMapFileName, "PNG");
}

marcel
20th April 2007, 22:20
Why don't you try synchronizing the chart creation with grabWidget(). Can't you emit a signal or set a flag somewhere to indicate that a certain chart has been finished and can be saved?

Regards

VireX
21st April 2007, 06:25
Perhaps it is a problem with Qt3s limitations, have you tried using Qt4?

Uwe
23rd April 2007, 09:00
This is not really an answer to your question, but note that grabWidget is a suboptimal way to save plots. Better use QwtPlot::print(QPaintDevice&, ...) instead.

QwtPlot::print renders the plot to any rect in the resolution of your paint device + you can save it as vector graphics (f.e. Postscript, PDF, SVG). If you render to a QPrinter you can have Encapsulated Postscript with a much higher precision than on screen. If you render to a QPixmep you can have any format supported by QImageIO and if you render to a QPicture you can even have SVG. ( With Qt4 you can also render to PDF. )

Uwe

conglu
23rd April 2007, 16:46
Why don't you try synchronizing the chart creation with grabWidget(). Can't you emit a signal or set a flag somewhere to indicate that a certain chart has been finished and can be saved?

Regards

I used a QTimer to activate a "slot" to print these pictures, but the components were still missing. Actually, I tried QTimer::start(), singleShot(), and even QThread. All same result.

Maybe this is a limitation of QT3.x just like VireX said. But anyone can comfirm it?

Seems I may need to go up to QT4. :(

Thanks again, guys.

conglu
23rd April 2007, 18:53
I find a way to solve this problem. Before the charts are created, show every single tab manually. Then everything is all right. :( My thought is that the prblem maybe caused by QwtPlot instead of QPixmap.

Uwe
23rd April 2007, 20:05
Neither QPixmap nor QwtPlot: you can't grab something that is not already there.

1) The geometry of the plot is triggered by resize events. I haven't checked it myself, but I expect that a plot, that is on a hidden tab, that has never been shown, never got one.

2) The content of the plot is rendered by QwtPlot::replot. If you don't call it manually and autoReplot is off, the first replot is done in QwtPlot::polish, what is also not called, if the tab has not been shown once.

So I recommend to call QwtPlot::replot manually (after construction) and again, use QwtPlot::print, that doesn't need resizeEvents and is the better solution anyway.

HTH,
Uwe

conglu
24th April 2007, 14:42
Neither QPixmap nor QwtPlot: you can't grab something that is not already there.

1) The geometry of the plot is triggered by resize events. I haven't checked it myself, but I expect that a plot, that is on a hidden tab, that has never been shown, never got one.

The images are there. I got them using the same code for the replay of a single data file. But after I tried to apply my application to multi data files, the code stops working. Since the QTimer event does not run until the FOR loop for multi-file stops.


2) The content of the plot is rendered by QwtPlot::replot. If you don't call it manually and autoReplot is off, the first replot is done in QwtPlot::polish, what is also not called, if the tab has not been shown once.

I called QwtPlot::replot(), polish(), and QTabWidget::showPage() before printing a tab. None of them works.


So I recommend to call QwtPlot::replot manually (after construction) and again, use QwtPlot::print, that doesn't need resizeEvents and is the better solution anyway.

HTH,
Uwe


I am going to try QwtPlot::print(), and let you guys know what will happen.

Thanks again.