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?



  • @Wieland

    Yes, it returns true.

    process.isOpen() - returns false.



  • Good. That means that "cmd.exe" has been started successfully. But QProcess::startDetached() is static, so it's not related to your process object. In other words: process has not been started. To start process, call the non-static process.start(...) . You can't use QProcess::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 and finished 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?



  • @Wieland

    Maybe the problem is with connect?


  • Lifetime Qt Champion

    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();
    }
    


  • @Wieland

    Now it works. Thanks for example code.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.