Thomas Mader
2006-02-09 15:07:04 UTC
Hi all,
I'm trying to plot from out of a thread, see code below. Unfortunatly, the program immediately crashes in replot. It helps to remove
QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
and replace
canvas.repaint(canvas.contentsRect());
by
canvas.update(canvas.contentsRect());
But occasionally it crashes despite these changes. Does anybody know the correct way to plot out of a QThread?
I' m using Qt 4.1, the open source Mingw compiler and the newest Qwt 5.0.
Regards
Thomas
....
PaintPltCurves plotThread;
plotThread.mwnd = mainWindw;
....
void TestPltMainWindow::startPlot() {
plotThread.start();
}
void PaintPltCurves::run() {
double* x = mwnd->x;
double* y = mwnd->y;
mwnd->curv1->setRawData(x, y, 0);
mwnd->plotter->d_plot->replot(); **************************crash!!!!!!!
int numData = 500;
double d = 0, delta = 3.14/10;
mwnd->plotter->d_plot->canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, true);
for(int i = 0; i < numData; ++i) {
x[i] = d;
y[i] = sin(d);
d += delta;
if(i > 0) {
mwnd->curv1->setRawData(x, y, i);
mwnd->curv1->draw(i-1, i);
msleep(50);
}
}
}
void QwtPlot::replot()
{
bool doAutoReplot = autoReplot();
setAutoReplot(false);
updateAxes();
/*
Maybe the layout needs to be updated, because of changed
axes labels. We need to process them here before painting
to avoid that scales and canvas get out of sync.
*/
#if QT_VERSION >= 0x040000
// QApplication::sendPostedEvents(this, QEvent::LayoutRequest); *********************************************************
#else
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
#endif
QwtPlotCanvas &canvas = *d_data->canvas;
canvas.invalidatePaintCache();
/*
In case of cached or packed painting the canvas
is repainted completely and doesn't need to be erased.
*/
const bool erase =
!canvas.testPaintAttribute(QwtPlotCanvas::PaintPacked)
&& !canvas.testPaintAttribute(QwtPlotCanvas::PaintCached);
#if QT_VERSION >= 0x040000
const bool noBackgroundMode = canvas.testAttribute(Qt::WA_NoBackground);
if ( !erase && !noBackgroundMode )
canvas.setAttribute(Qt::WA_NoBackground, true);
canvas.update(canvas.contentsRect()); **********************************************************************
if ( !erase && !noBackgroundMode )
canvas.setAttribute(Qt::WA_NoBackground, false);
#else
canvas.repaint(canvas.contentsRect(), erase);
#endif
setAutoReplot(doAutoReplot);
}
I'm trying to plot from out of a thread, see code below. Unfortunatly, the program immediately crashes in replot. It helps to remove
QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
and replace
canvas.repaint(canvas.contentsRect());
by
canvas.update(canvas.contentsRect());
But occasionally it crashes despite these changes. Does anybody know the correct way to plot out of a QThread?
I' m using Qt 4.1, the open source Mingw compiler and the newest Qwt 5.0.
Regards
Thomas
....
PaintPltCurves plotThread;
plotThread.mwnd = mainWindw;
....
void TestPltMainWindow::startPlot() {
plotThread.start();
}
void PaintPltCurves::run() {
double* x = mwnd->x;
double* y = mwnd->y;
mwnd->curv1->setRawData(x, y, 0);
mwnd->plotter->d_plot->replot(); **************************crash!!!!!!!
int numData = 500;
double d = 0, delta = 3.14/10;
mwnd->plotter->d_plot->canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, true);
for(int i = 0; i < numData; ++i) {
x[i] = d;
y[i] = sin(d);
d += delta;
if(i > 0) {
mwnd->curv1->setRawData(x, y, i);
mwnd->curv1->draw(i-1, i);
msleep(50);
}
}
}
void QwtPlot::replot()
{
bool doAutoReplot = autoReplot();
setAutoReplot(false);
updateAxes();
/*
Maybe the layout needs to be updated, because of changed
axes labels. We need to process them here before painting
to avoid that scales and canvas get out of sync.
*/
#if QT_VERSION >= 0x040000
// QApplication::sendPostedEvents(this, QEvent::LayoutRequest); *********************************************************
#else
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
#endif
QwtPlotCanvas &canvas = *d_data->canvas;
canvas.invalidatePaintCache();
/*
In case of cached or packed painting the canvas
is repainted completely and doesn't need to be erased.
*/
const bool erase =
!canvas.testPaintAttribute(QwtPlotCanvas::PaintPacked)
&& !canvas.testPaintAttribute(QwtPlotCanvas::PaintCached);
#if QT_VERSION >= 0x040000
const bool noBackgroundMode = canvas.testAttribute(Qt::WA_NoBackground);
if ( !erase && !noBackgroundMode )
canvas.setAttribute(Qt::WA_NoBackground, true);
canvas.update(canvas.contentsRect()); **********************************************************************
if ( !erase && !noBackgroundMode )
canvas.setAttribute(Qt::WA_NoBackground, false);
#else
canvas.repaint(canvas.contentsRect(), erase);
#endif
setAutoReplot(doAutoReplot);
}