Problem with QProcess
-
Hi! I want to read the cmd output.
My code:
QProcess process; process.startDetached("cmd.exe", arguments); process.setOpenMode(QIODevice::ReadOnly); process.waitForFinished(); qDebug() << process.readAllStandardOutput();
The problem is I get error:
C2248: 'QIODevice::setOpenMode': cannot access protected member declared in class 'QIODevice'
, otherwise I get:
QIODevice::read (QProcess): device not open
.So how to fix this?
-
Hi! Does
process.startDetached(...)
return true? -
Hi! Does
process.startDetached(...)
return true?@Wieland
Yes, it returns true.
process.isOpen()
- returns false. -
Good. That means that "cmd.exe" has been started successfully. But
QProcess::startDetached()
isstatic
, so it's not related to yourprocess
object. In other words:process
has not been started. To startprocess
, call the non-staticprocess.start(...)
. You can't useQProcess::readAllStandardOutput
together with a detached process. -
Good. That means that "cmd.exe" has been started successfully. But
QProcess::startDetached()
isstatic
, so it's not related to yourprocess
object. In other words:process
has not been started. To startprocess
, call the non-staticprocess.start(...)
. You can't useQProcess::readAllStandardOutput
together with a detached process.@Wieland
I have tried
process.start("cmd.exe", arguments);
but it freezes my application window? -
Sure it freezes your application, because you're blocking the GUI thread with
waitForFinished
until "cmd.exe" terminates.Connect to the signals
started
andfinished
instead. -
Sure it freezes your application, because you're blocking the GUI thread with
waitForFinished
until "cmd.exe" terminates.Connect to the signals
started
andfinished
instead.@Wieland
Ok. I will fix and check it. Thanks.
I have added started signal:
QProcess *process = new QProcess(); connect(process, &QProcess::started, this, &TestSettings::test); process->start("cmd.exe", arguments); void TestSettings::test() { qDebug() << process->readAllStandardOutput(); }
But nothing outputs?
-
Sure it freezes your application, because you're blocking the GUI thread with
waitForFinished
until "cmd.exe" terminates.Connect to the signals
started
andfinished
instead.@Wieland
Maybe the problem is with connect?
-
You should connect the readyReadStandardOutput and the readyReadStandardError signals if you want to see something when your command runs.
The started signal only tells you that the process successfully started, that doesn't mean it has written anything on the standard output or error channel.
-
Hi, look:
main.cpp
#include <QApplication> #include "myclass.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MyClass mc; QObject::connect(&mc, &MyClass::completed, &a, &QApplication::quit); mc.begin(); return a.exec(); }
myclass.h
#ifndef MYCLASS_H #define MYCLASS_H #include <QObject> #include <QProcess> class MyClass : public QObject { Q_OBJECT public: explicit MyClass(QObject *parent = nullptr); signals: void completed(); public slots: void begin(); private slots: void onStarted(); void onErrorOccurred(QProcess::ProcessError error); void onFinished(int exitCode, QProcess::ExitStatus exitStatus); void onReadyReadStandardOutput(); private: QProcess m_process; }; #endif // MYCLASS_H
myclass.cpp
#include "myclass.h" #include <Qtimer> #include <QDebug> MyClass::MyClass(QObject *parent) : QObject(parent) { connect(&m_process, &QProcess::started, this, &MyClass::onStarted); connect(&m_process, &QProcess::errorOccurred, this, &MyClass::onErrorOccurred); connect(&m_process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &MyClass::onFinished); connect(&m_process, &QProcess::readyReadStandardOutput, this, &MyClass::onReadyReadStandardOutput); } void MyClass::begin() { m_process.start("cmd.exe", QStringList()); } void MyClass::onStarted() { qDebug() << "Started"; QTimer::singleShot(2000, &m_process, &QProcess::kill); } void MyClass::onErrorOccurred(QProcess::ProcessError error) { qDebug() << QString("Error occurred, error=%1").arg(static_cast<int>(error)); } void MyClass::onFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << QString("Finished, exitCode=%1, exitStatus=%2").arg(static_cast<int>(exitCode)) .arg(static_cast<int>(exitStatus)); emit completed(); } void MyClass::onReadyReadStandardOutput() { qDebug() << m_process.readAllStandardOutput(); }
-
Hi, look:
main.cpp
#include <QApplication> #include "myclass.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MyClass mc; QObject::connect(&mc, &MyClass::completed, &a, &QApplication::quit); mc.begin(); return a.exec(); }
myclass.h
#ifndef MYCLASS_H #define MYCLASS_H #include <QObject> #include <QProcess> class MyClass : public QObject { Q_OBJECT public: explicit MyClass(QObject *parent = nullptr); signals: void completed(); public slots: void begin(); private slots: void onStarted(); void onErrorOccurred(QProcess::ProcessError error); void onFinished(int exitCode, QProcess::ExitStatus exitStatus); void onReadyReadStandardOutput(); private: QProcess m_process; }; #endif // MYCLASS_H
myclass.cpp
#include "myclass.h" #include <Qtimer> #include <QDebug> MyClass::MyClass(QObject *parent) : QObject(parent) { connect(&m_process, &QProcess::started, this, &MyClass::onStarted); connect(&m_process, &QProcess::errorOccurred, this, &MyClass::onErrorOccurred); connect(&m_process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &MyClass::onFinished); connect(&m_process, &QProcess::readyReadStandardOutput, this, &MyClass::onReadyReadStandardOutput); } void MyClass::begin() { m_process.start("cmd.exe", QStringList()); } void MyClass::onStarted() { qDebug() << "Started"; QTimer::singleShot(2000, &m_process, &QProcess::kill); } void MyClass::onErrorOccurred(QProcess::ProcessError error) { qDebug() << QString("Error occurred, error=%1").arg(static_cast<int>(error)); } void MyClass::onFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << QString("Finished, exitCode=%1, exitStatus=%2").arg(static_cast<int>(exitCode)) .arg(static_cast<int>(exitStatus)); emit completed(); } void MyClass::onReadyReadStandardOutput() { qDebug() << m_process.readAllStandardOutput(); }
@Wieland
Now it works. Thanks for example code.