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. Starting QProcess inside a thread
Forum Updated to NodeBB v4.3 + New Features

Starting QProcess inside a thread

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 8.0k Views 3 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.
  • T Offline
    T Offline
    testus
    wrote on last edited by
    #1

    I have been struggling with this basic problem for a while now.
    I’m trying to start a QProcess from a thread. Starting the process works and the process runs correctly but my problem is that the finished() signal is never emitted.

    Here is my example:

    My class variables are

    std::atomic<bool>  recording;
    QProcess proc;
    std::unique_ptr<std::thread> recordingThread;
    

    The class:

    Recorder::Recorder(ParentClass *parent): QObject(parent){
    	
    	connect(&proc,SIGNAL(finished(int)),this,SLOT(finishedFFMPEG())); 
    }
    
    void Recorder::start(){
    
    	if (!recordingThread){
    		recording = true;
    		recordingThread.reset(new std::thread(&Recorder::recordThread, this));
    	}
    }
    
    void Recorder::recordThread(){
    	
    	while(recording){
    		//writing frame
    	}
    	proc.start("C:\\ffmpeg.exe", QStringList() <<"-i"<< picDir.c_str() << "-r"<< "30" << "-vcodec"<< "ffv1" << filename.c_str());
    	proc.waitForStarted();      
    }
    
    void Recorder::stop(){
    	
    	if (recordingThread) {
    		recording = false;
    		recordingThread->join(); recordingThread.reset();  
    	}
    }
    
    void Recorder::finishedFFMPEG(){
    	qDebug() << "finished";
    }
    

    start() and stop() are called from another non-GUI thread in my ParentClass.

    I tried everything from using pointers, running my recordThread() as a QThread and starting the QProcess in the stop() function but I simply never receive the finished() signal from the process. The process itself is being executed correctly. I know the problem lies in the different event loops.

    How can I achieve my goal of starting a process after the recordThread() finishes and catching the QProcess finished() signal?

    1 Reply Last reply
    0
    • jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by
      #2

      It looks like there's no use of an event loop in the thread that starts the process. Without this or the use of a function that blocks until the process terminates, process termination won't be detected. In general, Qt's asynchronous interfaces depend on the event loop or triggering via a synchronous (relatively speaking) interface.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      T 1 Reply Last reply
      0
      • jeremy_kJ jeremy_k

        It looks like there's no use of an event loop in the thread that starts the process. Without this or the use of a function that blocks until the process terminates, process termination won't be detected. In general, Qt's asynchronous interfaces depend on the event loop or triggering via a synchronous (relatively speaking) interface.

        T Offline
        T Offline
        testus
        wrote on last edited by
        #3

        I know it has to do with the event loop but I can't find a way to make it work. I can't just block recordThread() until the process is finished because I need a new recordThread() to be able to start while the process is still running. Do you have any suggestion how I can achieve my goal?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          Since you are using Qt why not use a QThread ? But first thing, are you sure you need a thread at all to call QProcess ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • T Offline
            T Offline
            testus
            wrote on last edited by
            #5

            I'm not sure if you read the main post as I stated that I did try running it as a QThread. The QProcess has to run after the recordThread() finishes its task.

            1 Reply Last reply
            0
            • jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #6

              Presuming that the thread structure in use is appropriate, and the presence of a main thread running QCoreApplication::exec(), you can move the QProcess object to the main thread with QObject::moveToThread.

              void Thread::run()
              {
                  QProcess *process = new QProcess();
                  connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(done()));
                  process->start(program, QStringList());
                  if (!process->waitForStarted())
                      qDebug() << "error";
                  else
                      process->moveToThread(QCoreApplication::instance()->thread());
              }
              
              void Thread::done()
              {
                  qDebug() << "process done";
              }
              

              Another option is to use a QObject previously associated with the main thread with a slot that starts the external process.

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Yes, I did read it but misinterpreted your use of QThread.

                You should rather split responsibilities here. Have your recording thread do only that: recording. And once it's done make it emit a signal that you will connect to a slot that will start the ffmpeg QProcess. That way you can also encapsulate ffmpeg so that you can retrieve its output to check that everything is going fine.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                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