Why isn't my repaint() shown?
-
@Perdrix You should not block the Qt event loop. Using processEvents() is a dirty work around which may or may not work. Move long running calculations into a thread.
@jsulm https://forum.qt.io/topic/163776/
He does not care
-
I do very much care, but found that I can't move the invocation of QwtPlot::replot() into a thread. I tried.
@Perdrix
I don't know the details of your situation. However, I assumeQwtPlot::replot()causes a UI update. The Qt rule is: you must not attempt to update the UI from any secondary thread, only the main one.What you are supposed to do is move all calculations to a secondary thread. Then maybe have that emit a signal when done. At that point the main thread has a slot on that and does any updates or repaints. The intention is that time consuming calculations are removed from the main thread, hopefully making it "smoother", though the redraw has to be from main. Is that what you are doing?
-
Sure, I totally get that, and I've done precisely that for the interpolation code. But QwtPlot::replot() is not in my control and does block the event loop (it uses QFuture::waitForFinished() rather than using a QFutureWatcher and handling the
finishedsignal). -
Sure, I totally get that, and I've done precisely that for the interpolation code. But QwtPlot::replot() is not in my control and does block the event loop (it uses QFuture::waitForFinished() rather than using a QFutureWatcher and handling the
finishedsignal).@Perdrix
Good that you know about UI and threads. I don't get the stuff aboutQwtPlot::replot()and it usingQFuture::waitForFinished(), I don't see evidence for that. Nor do I see where you call it in your code. Unless you mean there is a call to it elsewhere in your own project, and that useswaitForFinished()? In which case you may need to alter that code? That's all I know. -
As I said Qwt isn't in my control. It's an external library. The code that was connected to showXXXX signals called QwtPlot::replot.
@Perdrix
I get that but you wroteBut QwtPlot::replot() is not in my control and does block the event loop (it uses QFuture::waitForFinished() rather than using a QFutureWatcher and handling the finished signal).
I don't get the
QFuturepart, you haven't explained. What uses "QFuture::waitForFinished()rather than ..."? The code ofQwtPlot::replot()from Qwt people? I don't see that. Code in an external library callsQwtPlot::replot()and also has its ownQFuture::waitForFinished(), is that what you are saying? I don't know, to me it's most unclear. -
QwtPlot::replot() is part of the Qwt library which I am using. For a spectrogram plot that eventually calls QwtPlotRasterItem::compose() which does:
QVector< QFuture< void > > futures; futures.reserve( numThreads - 1 ); for ( uint i = 0; i < numThreads; i++ ) { QRect tile( 0, i * numRows, image.width(), numRows ); if ( i == numThreads - 1 ) { tile.setHeight( image.height() - i * numRows ); qwtToRgba( &image, &alphaImage, tile, m_data->alpha ); } else { futures += QtConcurrent::run( &qwtToRgba, &image, &alphaImage, tile, m_data->alpha ); } } for ( int i = 0; i < futures.size(); i++ ) futures[i].waitForFinished();which completely blocks the Qt event loop until it finishes.
-
QwtPlot::replot() is part of the Qwt library which I am using. For a spectrogram plot that eventually calls QwtPlotRasterItem::compose() which does:
QVector< QFuture< void > > futures; futures.reserve( numThreads - 1 ); for ( uint i = 0; i < numThreads; i++ ) { QRect tile( 0, i * numRows, image.width(), numRows ); if ( i == numThreads - 1 ) { tile.setHeight( image.height() - i * numRows ); qwtToRgba( &image, &alphaImage, tile, m_data->alpha ); } else { futures += QtConcurrent::run( &qwtToRgba, &image, &alphaImage, tile, m_data->alpha ); } } for ( int i = 0; i < futures.size(); i++ ) futures[i].waitForFinished();which completely blocks the Qt event loop until it finishes.