Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why isn't my repaint() shown?
Qt 6.12 LTS is out! See what's new in the release blog

Why isn't my repaint() shown?

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 2.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • PerdrixP Perdrix

    I've got some code in my QDialog sub-class that is triggered when a QFuture finishes:

    
    		connect(this, &QualityChart::showEccentricity,
    			this, &QualityChart::plotEccentricity, Qt::QueuedConnection);
    		connect(this, &QualityChart::showFWHM,
    			this, &QualityChart::plotFWHM, Qt::QueuedConnection);
    
    void QualityChart::interpolationFinished()
    {
    	interpolating = false;
    	progressBar->reset();
    	message->setText(tr("Calculating contour plot.  Please be patient."));
            update();
    	QCoreApplication::processEvents();
    
    	if (!cancelled)
    	{
    		ZTRACE_RUNTIME("Interpolation complete");
    		//
    		// Show the appropriate chart
    		//
    		if (radioEccentricity->isChecked())
    		{
    			QTimer::singleShot(100,
    				[this]()
    				{
    					emit showEccentricity();
    				});
    		}
    		else
    		{
    			QTimer::singleShot(100,
    				[this]()
    				{
    					emit showFWHM();
    				});
    
    		}
    	}
    	else
    	{
    		ZTRACE_RUNTIME("Interpolation cancelled");
    		reject();
    	}
    }
    

    I was expecting the update to the message and the progress bar to be handled before the moderately slow code connected to the emitted signals was run, but that's not what happens, the results of (e.g. plotEccentricity() are displayed and the message update and progress bar update only happen then.

    I thought that by invoking e.g. plotEccentricity using a single shot would allow the update to be proceessed but clearly not.

    What am I missing here?

    Thanks David

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #2

    @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.

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    Christian EhrlicherC 1 Reply Last reply
    1
    • jsulmJ jsulm

      @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.

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #3

      @jsulm https://forum.qt.io/topic/163776/

      He does not care

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by
        #4

        I do very much care, but found that I can't move the invocation of QwtPlot::replot() into a thread. I tried.

        JonBJ 1 Reply Last reply
        0
        • PerdrixP Perdrix

          I do very much care, but found that I can't move the invocation of QwtPlot::replot() into a thread. I tried.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #5

          @Perdrix
          I don't know the details of your situation. However, I assume QwtPlot::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?

          1 Reply Last reply
          0
          • PerdrixP Offline
            PerdrixP Offline
            Perdrix
            wrote on last edited by Perdrix
            #6

            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 finished signal).

            JonBJ 1 Reply Last reply
            1
            • PerdrixP Perdrix

              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 finished signal).

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #7

              @Perdrix
              Good that you know about UI and threads. I don't get the stuff about QwtPlot::replot() and it using QFuture::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 uses waitForFinished()? In which case you may need to alter that code? That's all I know.

              1 Reply Last reply
              0
              • PerdrixP Offline
                PerdrixP Offline
                Perdrix
                wrote on last edited by
                #8

                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.

                JonBJ 1 Reply Last reply
                0
                • PerdrixP Perdrix

                  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.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #9

                  @Perdrix
                  I get that but you wrote

                  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 finished signal).

                  I don't get the QFuture part, you haven't explained. What uses "QFuture::waitForFinished() rather than ..."? The code of QwtPlot::replot() from Qwt people? I don't see that. Code in an external library calls QwtPlot::replot() and also has its own QFuture::waitForFinished(), is that what you are saying? I don't know, to me it's most unclear.

                  1 Reply Last reply
                  0
                  • PerdrixP Offline
                    PerdrixP Offline
                    Perdrix
                    wrote on last edited by
                    #10

                    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.

                    JonBJ 1 Reply Last reply
                    1
                    • PerdrixP Perdrix

                      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.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #11

                      @Perdrix Fair enough, I had not understood there was such in Qwt code.

                      1 Reply Last reply
                      0
                      • PerdrixP Offline
                        PerdrixP Offline
                        Perdrix
                        wrote on last edited by
                        #12
                        This post is deleted!
                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt
                        • Unsolved