[ fromfile: qprocess.xml id: qprocess ]
Now consider a simple example that starts a process and views its continually running output.[67]
Example 17.1. src/logtail/logtail.h
Example 17.2. src/logtail/logtail.cpp
[ . . . . ] LogTail::LogTail(QString fn) { connect (this, SIGNAL(readyReadStandardOutput()), this, SLOT(logOutput())); QStringList argv; argv << "-f" << fn; start("tail", argv); } LogTail::~LogTail() { terminate(); }
The child process can be treated as a sequential I/O device with two predefined output channels that represent two separate streams of data: stdout
and stderr.
The parent process can select an output channel with setReadChannel()
(default is stdout).
The signal readyReadStandardOutput()
is emitted when data is available on the selected channel of the child process.
The parent process can then read its output by calling read()
, readLine()
, or getChar()
.
If the child process has standard input enabled, the parent can use write()
to send data to it.
Example 17.3. src/logtail/logtail.cpp
[ . . . . ] // tail sends its output to stdout. void LogTail::logOutput() { QByteArray bytes = readAllStandardOutput(); QStringList lines = QString(bytes).split("\n"); foreach (QString line, lines) { emit logString(line); } }
The use of signals eliminates the need for a read loop.
When there is no more input to be read, the slot will no longer be called.
Signals and slots make concurrent code much simpler to read, because they hide the event-handling and dispatching code.
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); tail.connect (&tail, SIGNAL(logString(const QString&)), &textEdit, SLOT(append(const QString&))); textEdit.show(); return app.exec(); }
Figure 17.1 is a screenshot of the running program.
The demo runs until terminated, after which you must also kill the top
job, whose [job number] and process id were displayed just after it was launched.
[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.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |