Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    QtConcurrent::map() vs. QtConcurrent::run() for member function

    General and Desktop
    3
    6
    2577
    Loading More Posts
    • 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
      edtasker last edited by

      I have a QWidget class called "createCPInput" with a public member function "void generateAxtCPseq()" and a slot "void on_generateCPInputButton_clicked()". the function generateAxtCPseq() can take a long time to run so I run it within "on_generateCPInputButton_clicked()" using QtConcurrent::run() so that it runs in a separate thread.

      I want to be able to get progress signals and be able to cancel the thread, these features aren't compatible for QtConcurrent::run() but are compatible for QtConcurrent::map(). I haven't been able to figure out a way to run generateAxtCPseq() using QtConcurrent::map().

      If anyone has some suggestions that would be great.

      Here is the relevant code I have at the moment which runs fine but doesn't allow me the functionality I require:
      createcpinput.h

      @
      public:
      void generateAxtCPSeq();

      private slots:
      void on_generateCPInputButton_clicked();
      @

      createcpinput.cpp
      @
      void createCPInput::on_generateCPInputButton_clicked(){
      typedef QFutureWatcher<void> voidWatcher;
      voidWatcher *axtWatcher = new voidWatcher(this);
      axtWatcher->setFuture(QtConcurrent::run(this,&createCPInput::generateAxtCPSeq));
      }

      void createCPInput::generateAxtCPSeq(){
      //Computationally expensive task
      }
      @

      1 Reply Last reply Reply Quote 0
      • M
        MuldeR last edited by

        QtConcurrent::map() has the following interface:
        @map(Sequence &sequence, MapFunction function)@

        Hence you need a Sequence, containing the items to be processed, plus a MapFunction, which will be called once for each item to be processed.

        Also your MapFunction function must take a reference to an item as input and it must process that item. It can not be an arbitrary function!

        BTW: The reason why QtConcurrent::map() can be "cancelled" is because it will call your function once for each item. So it can simply stop calling your function before all items have been processed, when "cancellation" is requested. It still cannot "abort" a single call of your function!

        __

        See also:
        http://qt-project.org/doc/qt-4.8/qtconcurrent-map-main-cpp.html

        My OpenSource software at: http://muldersoft.com/

        Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

        Go visit the coop: http://youtu.be/Jay...

        1 Reply Last reply Reply Quote 0
        • E
          edtasker last edited by

          Thanks MuldeR for the reply.

          So, It seems like I'm going down the wrong path for what I want to do.

          The reason generateAxtCPSeq() takes a long time is because it reads in large data files and writes out a large amount of data. Initially I had this running in the same thread when on_generateCPInputButton_clicked() was called. This was causing my GUI to be non-responsive. After some searching I found this: http://doc.qt.digia.com/qq/qq27-responsive-guis.html. But because I call the function generateAxtCPSeq() only once there isn't a way to cancel it or get progress signals from it.

          Is there a way to perform the reading and writing in another thread but be able to cancel and get progress reports from it? it doesn't seem obvious because the reading and writing needs to happen sequentially (reading in line by line).

          1 Reply Last reply Reply Quote 0
          • hskoglund
            hskoglund last edited by

            Hi, perhaps instead try a "QThread class":https://qt-project.org/doc/qt-5/qthread.html . And you can use signal/slots for cancels and process reports.

            1 Reply Last reply Reply Quote 0
            • M
              MuldeR last edited by

              You cannot abort generateAxtCPSeq(), unless that function offers a way to do so! Of course you could run the function is a separate thread, e.g. by using QThread. Then you could simply kill the thread in order to "abort" the function. But this is inherently unsafe! You would kill the function at an arbitary position, resulting in undefined behavior. You can get resource leaks and other evils. Don't do this, if it can be avoided!

              Better change your function like this:
              @bool generateAxtCPSeq(volatile bool *abortFlag)
              {
              while((!completed) && (!(*abortFlag)))
              {
              doNextStep();
              }
              return complete;
              }@

              Then you could pass a pointer to a global "abortFlag" variable, which you set to false initially and which you can set to true, from the "main" thread, in order to abort the function call. This of course assumes your function can be broken down into a number of "short" steps.

              __

              It could look like this:

              @class MyThread : public QThread
              {
              public:
              MyThread(void)
              {
              m_success = m_abortFlag = false;
              }

              void abortFunction(void)
              {
                  m_abortFlag = true;
              }
              

              protected:
              virtual void run(void)
              {
              m_success = generateAxtCPSeq(&m_abortFlag);
              }

              volatile bool m_abortFlag;
              volatile bool m_success;
              

              };@
              @void MyDialog::startButtonPressed(void)
              {
              m_thread->start();
              }

              void MyDialog::abortButtonPresed(void)
              {
              m_thread->abortFunction();
              }@

              My OpenSource software at: http://muldersoft.com/

              Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

              Go visit the coop: http://youtu.be/Jay...

              1 Reply Last reply Reply Quote 0
              • E
                edtasker last edited by

                Thanks MuldeR that's really helpful :D

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post