Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. GUI events slow down long computations
QtWS25 Last Chance

GUI events slow down long computations

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 4 Posters 4.2k Views
  • 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.
  • E Offline
    E Offline
    engsml
    wrote on last edited by
    #1

    I have a file which has a lot of coordinates that I am plotting using QScatterSeries on a QChart. I have found that I can insert the function QCoreApplication::processEvents(); during the loop that plots each point and it will allow the user to use the QButtons while the function is performing the work required to plot. However, I have found that when the buttons are clicked, the run time slows down a lot for the plotting. I have tried many different solutions, one of which is plotting in intervals and using a buffer of type QVector<QPointF> and calling replace(); with the series. No matter what I do, it seems the processEvents(); function is what slows my application down. Any insight as to what I can do to fix the problem would be appreciated!

    My code is as follows:

    /* This function is called from a one-shot timer in the main view. It loops until it reaches the end of the array */
    
    void myClass::addPoints()
    {
       
        QVector<QPointF> arr = getData->getArray();  //From my data class
        int arrSize = 4096; //for incrementing in intervals
    
        for(int i = 0; i < arr.size(); i += arrSize) //Plots in increments of 4096
       {
          
          plot(arr, (i + 4096));
          //Sleep function here
    
        }
    
    }
    
    void myClass::plot(QVector<QPointF> arr, int size)
    {
        for(int i = begin; i < size; i++){
    
            //Appending all points
            series->append(arr.value(i).x(), arr.value(i).y());
    
            QCoreApplication::processEvents(); //The function I believe is causing the problems.
    
             //Some data manipulation is here
           }
    
        begin += 4096; //For increasing loop limits during the next loop
    }
    JonBJ 1 Reply Last reply
    0
    • E engsml

      I have a file which has a lot of coordinates that I am plotting using QScatterSeries on a QChart. I have found that I can insert the function QCoreApplication::processEvents(); during the loop that plots each point and it will allow the user to use the QButtons while the function is performing the work required to plot. However, I have found that when the buttons are clicked, the run time slows down a lot for the plotting. I have tried many different solutions, one of which is plotting in intervals and using a buffer of type QVector<QPointF> and calling replace(); with the series. No matter what I do, it seems the processEvents(); function is what slows my application down. Any insight as to what I can do to fix the problem would be appreciated!

      My code is as follows:

      /* This function is called from a one-shot timer in the main view. It loops until it reaches the end of the array */
      
      void myClass::addPoints()
      {
         
          QVector<QPointF> arr = getData->getArray();  //From my data class
          int arrSize = 4096; //for incrementing in intervals
      
          for(int i = 0; i < arr.size(); i += arrSize) //Plots in increments of 4096
         {
            
            plot(arr, (i + 4096));
            //Sleep function here
      
          }
      
      }
      
      void myClass::plot(QVector<QPointF> arr, int size)
      {
          for(int i = begin; i < size; i++){
      
              //Appending all points
              series->append(arr.value(i).x(), arr.value(i).y());
      
              QCoreApplication::processEvents(); //The function I believe is causing the problems.
      
               //Some data manipulation is here
             }
      
          begin += 4096; //For increasing loop limits during the next loop
      }
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @engsml said in GUI events slow down long computations:

      However, I have found that when the buttons are clicked, the run time slows down a lot for the plotting

      Well if these buttons cause code to be executed in the UI then that will/may slow down the chart processing, if that's what you mean.

      Otherwise, I imagine processEvents() will allow your QChart to repaint with its new points (which it would not otherwise do), so that would probably slow down the overall plot speed?

      E 1 Reply Last reply
      0
      • JonBJ JonB

        @engsml said in GUI events slow down long computations:

        However, I have found that when the buttons are clicked, the run time slows down a lot for the plotting

        Well if these buttons cause code to be executed in the UI then that will/may slow down the chart processing, if that's what you mean.

        Otherwise, I imagine processEvents() will allow your QChart to repaint with its new points (which it would not otherwise do), so that would probably slow down the overall plot speed?

        E Offline
        E Offline
        engsml
        wrote on last edited by
        #3

        @JonB My buttons do have code that is executed when they are pressed.
        If I don't press any buttons while the function is plotting, it plots quickly at a speed i'm happy with.

        What do you mean by 'repainting' from the QChart?

        JonBJ 1 Reply Last reply
        0
        • E engsml

          @JonB My buttons do have code that is executed when they are pressed.
          If I don't press any buttons while the function is plotting, it plots quickly at a speed i'm happy with.

          What do you mean by 'repainting' from the QChart?

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

          @engsml

          My buttons do have code that is executed when they are pressed.
          If I don't press any buttons while the function is plotting, it plots quickly at a speed i'm happy with.

          Well if you do interrupt the plotting to allow the UI to go off and process events (via your QCoreApplication::processEvents()) where it takes time executing some code, then yes it will slow down the overall appending/plotting of points inevitably. Would you not expect that? (I don't know whether you're doing enough computation to make separate thread worthwhile, that's another matter.)

          What do you mean by 'repainting' from the QChart?

          I have never used QChart. But I imagine (stand to be corrected) that when you add all those points the chart does actually paint them until the next time it hits QCoreApplication::processEvents(). That would normally be after you've added all the points, but putting processEvents() into your plotting loop will mean it paints as it goes along, slowing it down.

          One thing:

                  //Appending all points
                  series->append(arr.value(i).x(), arr.value(i).y());
          

          The series->append() appends just one point, not all of them, right? Assuming so, you don't want to call processEvents() after each point append, that's unnecessarily often, you want to call it once for each batch of, say, 4096 points, don't you?

          1 Reply Last reply
          1
          • E Offline
            E Offline
            engsml
            wrote on last edited by
            #5

            @JonB Thanks for your reply! I kind of expected it to be slow. I have read multiple cases where the GUI events would be in the main thread and all computation heavy functions are passed off into different threads.

            My plotting does 'paint'! I wish I could put in a video, but it pretty much adds the points as it goes along, making it look like it's being "painted" somewhat. Is this what you mean?

            I did try putting the processEvents(); function in the first loop, but it makes the GUI become unresponsive. I will run it through the debugger and see if there are any other reasons why it should be doing this.

            JonBJ 1 Reply Last reply
            0
            • E engsml

              @JonB Thanks for your reply! I kind of expected it to be slow. I have read multiple cases where the GUI events would be in the main thread and all computation heavy functions are passed off into different threads.

              My plotting does 'paint'! I wish I could put in a video, but it pretty much adds the points as it goes along, making it look like it's being "painted" somewhat. Is this what you mean?

              I did try putting the processEvents(); function in the first loop, but it makes the GUI become unresponsive. I will run it through the debugger and see if there are any other reasons why it should be doing this.

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

              @engsml
              Since you allow processEvents() after each single point append, I would expect you would see the chart repaint for every point. (Without that you would only see the whole chart at the end, in one single go.) This may be pretty as an animation, but it's bound to be slower (I would have thought) than making it so it only paints once on conclusion, or at least only between "batches" of new points. Depends what you want.

              It is true that if you have computation-heavy code you should really do that in a distinct thread from the UI thread, to retain responsiveness. However, the catch is that accessing the QChart/QSeries can only be done from the UI thread which created it. That means your series->append() call.

              One usually arranges for the computation thread to send a signal to the UI thread for the points it wants added to the chart. But in your case I don't see any actual heavy-duty computation going on, you seem to have all the coordinates you want already in some array. So you don't actually want to do any more than append the point, and I don't see that a separate thread is useful to you....

              E 1 Reply Last reply
              0
              • JonBJ JonB

                @engsml
                Since you allow processEvents() after each single point append, I would expect you would see the chart repaint for every point. (Without that you would only see the whole chart at the end, in one single go.) This may be pretty as an animation, but it's bound to be slower (I would have thought) than making it so it only paints once on conclusion, or at least only between "batches" of new points. Depends what you want.

                It is true that if you have computation-heavy code you should really do that in a distinct thread from the UI thread, to retain responsiveness. However, the catch is that accessing the QChart/QSeries can only be done from the UI thread which created it. That means your series->append() call.

                One usually arranges for the computation thread to send a signal to the UI thread for the points it wants added to the chart. But in your case I don't see any actual heavy-duty computation going on, you seem to have all the coordinates you want already in some array. So you don't actually want to do any more than append the point, and I don't see that a separate thread is useful to you....

                E Offline
                E Offline
                engsml
                wrote on last edited by
                #7

                @JonB Is there any way I can do something similar to processEvents() without compromising the speed or repainting the points? I've tried putting processEvents() outside the loop but the buttons are very slow to respond.

                1 Reply Last reply
                0
                • J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  I‘m Preto sure, that your Series Append function allows an append<QList<QPointF> > if you cange your Vector to a Qlist, you Could prevent the whole for loop 


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  E 2 Replies Last reply
                  0
                  • J.HilkJ J.Hilk

                    I‘m Preto sure, that your Series Append function allows an append<QList<QPointF> > if you cange your Vector to a Qlist, you Could prevent the whole for loop 

                    E Offline
                    E Offline
                    engsml
                    wrote on last edited by
                    #9

                    @J.Hilk I'll try that, thanks! Hopefully my file is not too big that it will slow down the GUI.

                    1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      I‘m Preto sure, that your Series Append function allows an append<QList<QPointF> > if you cange your Vector to a Qlist, you Could prevent the whole for loop 

                      E Offline
                      E Offline
                      engsml
                      wrote on last edited by
                      #10

                      @J.Hilk My file is too big ): the GUI is not responding when I try this.

                      JonBJ 1 Reply Last reply
                      0
                      • E engsml

                        @J.Hilk My file is too big ): the GUI is not responding when I try this.

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

                        @engsml
                        Hang on a minute. Let's look at your code, please:

                        int arrSize = 4096; //for incrementing in intervals
                        for(int i = 0; i < arr.size(); i += arrSize) //Plots in increments of 4096
                            plot(arr, (i + 4096));
                        

                        This passes first 0+4096, then 4096+4096, then 8192+4096, then....

                        void myClass::plot(QVector<QPointF> arr, int size)
                            for(int i = begin; i < size; i++){
                        

                        arr is always the original array. I presume (I'm not C++) begin is always 0. size is bigger (by 4096) every time plot is called.

                        Aren't you (re-)plotting more & more points --- specifically, all points from 0 up to where you have progressed to --- every time you call plot() in your batches?? Or am I going loopy?

                        E SGaistS 2 Replies Last reply
                        0
                        • JonBJ JonB

                          @engsml
                          Hang on a minute. Let's look at your code, please:

                          int arrSize = 4096; //for incrementing in intervals
                          for(int i = 0; i < arr.size(); i += arrSize) //Plots in increments of 4096
                              plot(arr, (i + 4096));
                          

                          This passes first 0+4096, then 4096+4096, then 8192+4096, then....

                          void myClass::plot(QVector<QPointF> arr, int size)
                              for(int i = begin; i < size; i++){
                          

                          arr is always the original array. I presume (I'm not C++) begin is always 0. size is bigger (by 4096) every time plot is called.

                          Aren't you (re-)plotting more & more points --- specifically, all points from 0 up to where you have progressed to --- every time you call plot() in your batches?? Or am I going loopy?

                          E Offline
                          E Offline
                          engsml
                          wrote on last edited by engsml
                          #12

                          @JonB the 'begin' variable also increases by 4096 each time. so the pattern goes:
                          begin: 0... size: 4096
                          begin: 4096.. size: 8192
                          begin: 8192... size: 12288 etc..
                          it increases at the bottom of the plot function, begin += 4096 :)

                          edit: the plot is correct and what is expected from my txt file, just reeeeaallly slow when buttons are pressed (presumably from the processEvents(); function in the loop)

                          JonBJ 2 Replies Last reply
                          0
                          • E engsml

                            @JonB the 'begin' variable also increases by 4096 each time. so the pattern goes:
                            begin: 0... size: 4096
                            begin: 4096.. size: 8192
                            begin: 8192... size: 12288 etc..
                            it increases at the bottom of the plot function, begin += 4096 :)

                            edit: the plot is correct and what is expected from my txt file, just reeeeaallly slow when buttons are pressed (presumably from the processEvents(); function in the loop)

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

                            @engsml said in GUI events slow down long computations:

                            the 'begin' variable also increases by 4096 each time.

                            Oh, you mean that's your variable you don't show but increment yourself. I was thinking it was some kind of std::list::begin iterator on the list of points.

                            Your plot would not have gone wrong, just it would contain loads of "duplicate" points. But I take the point about the buttons being the issue.

                            1 Reply Last reply
                            0
                            • E engsml

                              @JonB the 'begin' variable also increases by 4096 each time. so the pattern goes:
                              begin: 0... size: 4096
                              begin: 4096.. size: 8192
                              begin: 8192... size: 12288 etc..
                              it increases at the bottom of the plot function, begin += 4096 :)

                              edit: the plot is correct and what is expected from my txt file, just reeeeaallly slow when buttons are pressed (presumably from the processEvents(); function in the loop)

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

                              @engsml said in GUI events slow down long computations:

                              just reeeeaallly slow when buttons are pressed (presumably from the processEvents(); function in the loop)

                              I do think you ought explain what a button actually does? The whole point is that the processEvents() allows whatever code for on clicked to actually run, so of course if it does much stuff it's going to slow things down. If a button's click does basically nothing, then the overhead is much smaller. If you just click a button (rather than keep clicking it) which does nothing, it shouldn't take any more time than if you don't click a button (but still have processEvents() in the code), if you're saying it does?

                              E 1 Reply Last reply
                              0
                              • JonBJ JonB

                                @engsml said in GUI events slow down long computations:

                                just reeeeaallly slow when buttons are pressed (presumably from the processEvents(); function in the loop)

                                I do think you ought explain what a button actually does? The whole point is that the processEvents() allows whatever code for on clicked to actually run, so of course if it does much stuff it's going to slow things down. If a button's click does basically nothing, then the overhead is much smaller. If you just click a button (rather than keep clicking it) which does nothing, it shouldn't take any more time than if you don't click a button (but still have processEvents() in the code), if you're saying it does?

                                E Offline
                                E Offline
                                engsml
                                wrote on last edited by
                                #15

                                @JonB The buttons mainly do stuff like scroll left or right, set the range to autoscale the plot, zoom in/out and save a screenshot. All the methods are found in the QChart API and only have about 1 line of code each.

                                I can imagine the overlaps plot twice (i.e when begin is 4096 but also the end of the last loop when size was 4096) but I am not too sure if there are other duplicates. Am I missing something?

                                JonBJ 1 Reply Last reply
                                0
                                • E engsml

                                  @JonB The buttons mainly do stuff like scroll left or right, set the range to autoscale the plot, zoom in/out and save a screenshot. All the methods are found in the QChart API and only have about 1 line of code each.

                                  I can imagine the overlaps plot twice (i.e when begin is 4096 but also the end of the last loop when size was 4096) but I am not too sure if there are other duplicates. Am I missing something?

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

                                  @engsml
                                  Don't worry about what I said about duplicates. I'll assume your code is correct there. I just misunderstood what your begin was.

                                  I'm still not sure just what your expectation/experience is. If you press a button to change how the chart looks (like scrolling or zooming or whatever), every time you click it will do so. That will interrupt your adding of new points till the action is finished, so naturally the final, overall plot time will end up being longer. Would you not expect that?

                                  But if you do not click a button, but do have the processEvents() in there, the only extra thing that is happening is that the chart is getting redrawn (points added) as it goes along. Which will also be slower overall than not redrawing till the whole thing is finished.

                                  I still say you are calling processEvents() too frequently. You should use a batch size. If you say 4096 makes it too unresponsive, at least try 10% of that (400, 100, whatever) rather than calling it for every single point appended.

                                  E 1 Reply Last reply
                                  2
                                  • JonBJ JonB

                                    @engsml
                                    Don't worry about what I said about duplicates. I'll assume your code is correct there. I just misunderstood what your begin was.

                                    I'm still not sure just what your expectation/experience is. If you press a button to change how the chart looks (like scrolling or zooming or whatever), every time you click it will do so. That will interrupt your adding of new points till the action is finished, so naturally the final, overall plot time will end up being longer. Would you not expect that?

                                    But if you do not click a button, but do have the processEvents() in there, the only extra thing that is happening is that the chart is getting redrawn (points added) as it goes along. Which will also be slower overall than not redrawing till the whole thing is finished.

                                    I still say you are calling processEvents() too frequently. You should use a batch size. If you say 4096 makes it too unresponsive, at least try 10% of that (400, 100, whatever) rather than calling it for every single point appended.

                                    E Offline
                                    E Offline
                                    engsml
                                    wrote on last edited by
                                    #17

                                    @JonB Thanks for your help! I included this code snippet in my for loop (I created a variable to help track each 10th element). It seems to run much faster. I'll test it out a bit more and see what the 'magic number' is. Thanks so much again for all your help.

                                    if(currentIndex % 10 == 0)
                                    {
                                        QCoreApplication::processEvents();
                                    }
                                    JonBJ 1 Reply Last reply
                                    0
                                    • E engsml

                                      @JonB Thanks for your help! I included this code snippet in my for loop (I created a variable to help track each 10th element). It seems to run much faster. I'll test it out a bit more and see what the 'magic number' is. Thanks so much again for all your help.

                                      if(currentIndex % 10 == 0)
                                      {
                                          QCoreApplication::processEvents();
                                      }
                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by
                                      #18

                                      @engsml
                                      Yep, that's 1 in 10. Like I suggested, I'd be looking for more like 1 in 100 or 1 in 400 as being frequent enough. (I'm surprised that 4096 is too "lumpy" in the first place.)

                                      E 1 Reply Last reply
                                      1
                                      • JonBJ JonB

                                        @engsml
                                        Yep, that's 1 in 10. Like I suggested, I'd be looking for more like 1 in 100 or 1 in 400 as being frequent enough. (I'm surprised that 4096 is too "lumpy" in the first place.)

                                        E Offline
                                        E Offline
                                        engsml
                                        wrote on last edited by
                                        #19

                                        @JonB Yeah it seems 100 is a good number where it still remains fast and responsive. I'm pretty surprised too! My file is about 300,000 coordinates which is probably a lot less data than most large scale programs. I would've assumed Qt and C++ are quicker at processing it.

                                        JonBJ 1 Reply Last reply
                                        0
                                        • E engsml

                                          @JonB Yeah it seems 100 is a good number where it still remains fast and responsive. I'm pretty surprised too! My file is about 300,000 coordinates which is probably a lot less data than most large scale programs. I would've assumed Qt and C++ are quicker at processing it.

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

                                          @engsml
                                          300k points-odd is still a lot of points, though having no experience I don't know what to expect. I don't suppose your average end-user will notice each one of those. If you only add 1 in 10 of them you call processEvents() 10 times fewer for the same responsiveness. So if you have a lot of points you could sample or average and it would all be a lot quicker. Though that's probably very naughty :)

                                          E 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 Extensions
                                          • Unsolved