Get live output (and state) out of QProcess
-
Hi, I'm trying to get a live output out of a QProcess.
I decided to make 2 classes in one header file (thread
anddownload
). Both QThreads. One of them I put QProcess in and the other one used for reading/processing the output. But I've got a problem with that. I always get this error:QObject: Cannot create children for a parent that is in a different thread. (Parent is QProcess(0x60fd60), parent's thread is QThread(0x6a7f90), current thread is download(0x60fd50) this error prints out 3 times
The only way that I found to not get this error is declaring QProcess in in
void run();
. I currently have it declared as a private member.thread.h:
#ifndef THREAD_H #define THREAD_H #include <QThread> #include <QDebug> #include <QProcess> class download : public QThread { Q_OBJECT public: bool getState() {return process.state();} QString getOut() {return process.readAll();} private: QProcess process; void run() override { process.start("curl", QStringList() << "url"); process.waitForFinished(-1); } signals: void update(QString); }; class Thread : public QThread { ... private: download dl; }; #endif // THREAD_H
thread.cpp:
... qDebug() << "process start"; dl.start(); while (dl.getState() != false) { qDebug() << dl.getOut(); msleep(100); } qDebug() << "finished"; ...
-
I managed to get it working.
This is how I did it:download.h
#ifndef DOWNLOAD_H #define DOWNLOAD_H #include <QObject> #include <QProcess> #include <QDebug> class download : public QObject { Q_OBJECT public: download(); void Main(); public slots: void start(); void stop(int, QProcess::ExitStatus); void getOutput(); private: QProcess process; }; #endif // DOWNLOAD_H
download.cpp
#include "download.h" download::download() { QObject::connect(&process, SIGNAL(started()), this, SLOT(start())); QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(stop(int, QProcess::ExitStatus))); QObject::connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(getOutput())); } void download::start() { qDebug() << "started"; } void download::stop(int, QProcess::ExitStatus) { qDebug() << "stopped"; } void download::getOutput() { qDebug() << process.readAll(); } void download::Main() { process.start("curl", QStringList() << "url"); process.waitForStarted(); }
-
Hi, I'm trying to get a live output out of a QProcess.
I decided to make 2 classes in one header file (thread
anddownload
). Both QThreads. One of them I put QProcess in and the other one used for reading/processing the output. But I've got a problem with that. I always get this error:QObject: Cannot create children for a parent that is in a different thread. (Parent is QProcess(0x60fd60), parent's thread is QThread(0x6a7f90), current thread is download(0x60fd50) this error prints out 3 times
The only way that I found to not get this error is declaring QProcess in in
void run();
. I currently have it declared as a private member.thread.h:
#ifndef THREAD_H #define THREAD_H #include <QThread> #include <QDebug> #include <QProcess> class download : public QThread { Q_OBJECT public: bool getState() {return process.state();} QString getOut() {return process.readAll();} private: QProcess process; void run() override { process.start("curl", QStringList() << "url"); process.waitForFinished(-1); } signals: void update(QString); }; class Thread : public QThread { ... private: download dl; }; #endif // THREAD_H
thread.cpp:
... qDebug() << "process start"; dl.start(); while (dl.getState() != false) { qDebug() << dl.getOut(); msleep(100); } qDebug() << "finished"; ...
- You don't need a thread for this task
- You create the QProcess instance in the main thread but access it in the thread created by QThread and therefore the warning - so create it in the thread you're accessing it (= inside run()) - but as already written it's not needed at all - see 1.
-
Hi, I'm trying to get a live output out of a QProcess.
I decided to make 2 classes in one header file (thread
anddownload
). Both QThreads. One of them I put QProcess in and the other one used for reading/processing the output. But I've got a problem with that. I always get this error:QObject: Cannot create children for a parent that is in a different thread. (Parent is QProcess(0x60fd60), parent's thread is QThread(0x6a7f90), current thread is download(0x60fd50) this error prints out 3 times
The only way that I found to not get this error is declaring QProcess in in
void run();
. I currently have it declared as a private member.thread.h:
#ifndef THREAD_H #define THREAD_H #include <QThread> #include <QDebug> #include <QProcess> class download : public QThread { Q_OBJECT public: bool getState() {return process.state();} QString getOut() {return process.readAll();} private: QProcess process; void run() override { process.start("curl", QStringList() << "url"); process.waitForFinished(-1); } signals: void update(QString); }; class Thread : public QThread { ... private: download dl; }; #endif // THREAD_H
thread.cpp:
... qDebug() << "process start"; dl.start(); while (dl.getState() != false) { qDebug() << dl.getOut(); msleep(100); } qDebug() << "finished"; ...
@Sucharek
Yes, withQProcess
as with otherQObject
s you cannot have it live in one thread and access it from a different thread.Why do you need threads for any of this, given that
QProcess
offers fully asynchronous operation for e.g. reading? Get rid ofwaitForFinished()
, get rid ofmsleep()
s, just usereadRead()
&finished()
signals fromQProcess
. -
Oh ok.
Well, I tried doing it like this:QProcess process; process.start("curl", QStringList() << "url"); while (process.state() == QProcess::Running) { qDebug() << process.readAll(); //prints nothing msleep(100); } qDebug() << process.readAll();
The while loop is looping forever.
@JonB, you said to use the
finished()
signal, but I'm not sure how to work with it. Should I useQObject::connect()
? If yes, how? -
Oh ok.
Well, I tried doing it like this:QProcess process; process.start("curl", QStringList() << "url"); while (process.state() == QProcess::Running) { qDebug() << process.readAll(); //prints nothing msleep(100); } qDebug() << process.readAll();
The while loop is looping forever.
@JonB, you said to use the
finished()
signal, but I'm not sure how to work with it. Should I useQObject::connect()
? If yes, how?@Sucharek said in Get live output (and state) out of QProcess:
The while loop is looping forever.
As already told you - use the proper QProcess signals .
-
@Sucharek said in Get live output (and state) out of QProcess:
The while loop is looping forever.
As already told you - use the proper QProcess signals .
@Christian-Ehrlicher alright, I tried using
finished()
, but it also doesn't work.
This is what I have:QProcess process; process.start("curl", QStringList() << "url"); QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(stop(int, QProcess::ExitStatus))); while (processRunning == 1) { qDebug() << "running"; msleep(100); }
I get this error:
QObject::connect: Cannot queue arguments of type 'QProcess::ExitStatus' (Make sure 'QProcess::ExitStatus' is registered using qRegisterMetaType().)
-
@Christian-Ehrlicher alright, I tried using
finished()
, but it also doesn't work.
This is what I have:QProcess process; process.start("curl", QStringList() << "url"); QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(stop(int, QProcess::ExitStatus))); while (processRunning == 1) { qDebug() << "running"; msleep(100); }
I get this error:
QObject::connect: Cannot queue arguments of type 'QProcess::ExitStatus' (Make sure 'QProcess::ExitStatus' is registered using qRegisterMetaType().)
Again: you don't need threads so don't use them. Create a QProcess instance, start the application you want and connect the finished() signal to your slot to read out the data you want.
-
Again: you don't need threads so don't use them. Create a QProcess instance, start the application you want and connect the finished() signal to your slot to read out the data you want.
@Christian-Ehrlicher I'm gonna be using that thread for something else. Should I create a new class just for QProcess?
-
@Christian-Ehrlicher I'm gonna be using that thread for something else. Should I create a new class just for QProcess?
@Sucharek said in Get live output (and state) out of QProcess:
I'm gonna be using that thread for something else
But the way you showed in your first post you're doing it completely wrong and we already told you so. Please read the documentation.
Should I create a new class just for QProcess?
No - why should you create a class for QProcess? Don't understand this question.
-
I managed to get it working.
This is how I did it:download.h
#ifndef DOWNLOAD_H #define DOWNLOAD_H #include <QObject> #include <QProcess> #include <QDebug> class download : public QObject { Q_OBJECT public: download(); void Main(); public slots: void start(); void stop(int, QProcess::ExitStatus); void getOutput(); private: QProcess process; }; #endif // DOWNLOAD_H
download.cpp
#include "download.h" download::download() { QObject::connect(&process, SIGNAL(started()), this, SLOT(start())); QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(stop(int, QProcess::ExitStatus))); QObject::connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(getOutput())); } void download::start() { qDebug() << "started"; } void download::stop(int, QProcess::ExitStatus) { qDebug() << "stopped"; } void download::getOutput() { qDebug() << process.readAll(); } void download::Main() { process.start("curl", QStringList() << "url"); process.waitForStarted(); }
-