17.1.  QProcess and Process Control

[ fromfile: qprocess.xml id: qprocess ]

Example 17.1. src/logtail/logtail.h

[ . . . . ]
#include <QObject>
#include <QProcess>
class LogTail : public QProcess {
    Q_OBJECT
  public:
    LogTail(QString fn = QString());
    ~LogTail();
  signals:
    void logString(const QString &str);
    
  public slots:
    void logOutput();
};
[ . . . . ]

Example 17.2. src/logtail/logtail.cpp

[ . . . . ]

LogTail::LogTail(QString fn) {
    connect (this, SIGNAL(readyReadStandardOutput()), 
        this, SLOT(logOutput()));       1
    QStringList argv;
     
    argv << "-f" << fn;                 2 
    start("tail", argv);                3
}
LogTail::~LogTail() {
    terminate();                        4
}

1

When there is input ready, call this slot.

2

tail -f filename

3

Returns immediately, and now there is a child process running, "attached" to this process. When this process exits, the child tail process will also terminate.

4

Attempts to terminate this process.


Example 17.3. src/logtail/logtail.cpp

[ . . . . ]

// tail sends its output to stdout.
void LogTail::logOutput() {             1
    QByteArray bytes = readAllStandardOutput();
    QStringList lines = QString(bytes).split("\n");
    foreach (QString line, lines) {
        emit logString(line); 
    }
}

1

Slot called whenever there is input to read.


Example 17.4. src/logtail/logtail.cpp

[ . . . . ]

int main (int argc, char* argv[]) {
    QApplication app(argc, argv);
    QStringList al = app.arguments(); 
    QTextEdit textEdit;
    textEdit.setWindowTitle("Debug");
    textEdit.setWindowTitle("logtail demo");
    QString filename;
    if (al.size() > 1) filename = al[1];
    LogTail tail(filename);             1
    tail.connect (&tail, SIGNAL(logString(const QString&)),
        &textEdit, SLOT(append(const QString&)));
    textEdit.show();
    return app.exec();
}

1

Create object, starts process too.


Figure 17.1. LogTail in use

LogTail in use



[67] tail -f runs forever showing whatever is appended to a file and is useful for showing the contents of a log file of a running process.

[68] Underscoring the value of the cross-platform QProcess API is the fact that the mechanism for one process to launch another differs considerably in the two leading operating system families. For more information about how it is handled in *nix systems, see the Wikipedia article Fork. The Microsoft Windows approach is described in Spawn.

[69] It is also possible to use startDetached() to start a process that can live after the parent process dies.