QProcess Class
The QProcess class is used to start external programs and to communicate with them. More...
| Header: | #include <QProcess> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core)target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
- List of all members, including inherited members
- QProcess is part of Input/Output and Networking.
Note: All functions in this class are reentrant.
Static Public Members
| QStringList | splitCommand(QStringView command) |
Detailed Description
Running a Process
To start a process, pass the name and command line arguments of the program you want to run as arguments to start(). Arguments are supplied as individual strings in a QStringList.
Alternatively, you can set the program to run with setProgram() and setArguments(), and then call start() or open().
For example, the following code snippet runs the analog clock example in the Fusion style on X11 platforms by passing strings containing "-style" and "fusion" as two items in the list of arguments:
QObject *parent;
...
QString program = "./path/to/Qt/examples/widgets/analogclock";
QStringList arguments;
arguments << "-style" << "fusion";
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
QProcess then enters the Starting state, and when the program has started, QProcess enters the Running state and emits started().
QProcess allows you to treat a process as a sequential I/O device. You can write to and read from the process just as you would access a network connection using QTcpSocket. You can then write to the process's standard input by calling write(), and read the standard output by calling read(), readLine(), and getChar(). Because it inherits QIODevice, QProcess can also be used as an input source for QXmlReader, or for generating data to be uploaded using QNetworkAccessManager.
When the process exits, QProcess reenters the NotRunning state (the initial state), and emits finished().
The finished() signal provides the exit code and exit status of the process as arguments, and you can also call exitCode() to obtain the exit code of the last process that finished, and exitStatus() to obtain its exit status. If an error occurs at any point in time, QProcess will emit the errorOccurred() signal. You can also call error() to find the type of error that occurred last, and state() to find the current process state.
Note: QProcess is not supported on VxWorks, iOS, tvOS, or watchOS.
Finding the Executable
The program to be run can be set either by calling setProgram() or directly in the start() call. The effect of calling start() with the program name and arguments is equivalent to calling setProgram() and setArguments() before that function and then calling the overload without those parameters.
QProcess interprets the program name in one of three different ways, similar to how Unix shells and the Windows command interpreter operate in their own command-lines:
- If the program name is an absolute path, then that is the exact executable that will be launched and QProcess performs no searching.
- If the program name is a relative path with more than one path component (that is, it contains at least one slash), the starting directory where that relative path is searched is OS-dependent: on Windows, it's the parent process' current working dir, while on Unix it's the one set with setWorkingDirectory().
- If the program name is a plain file name with no slashes, the behavior is operating-system dependent. On Unix systems, QProcess will search the
PATHenvironment variable; on Windows, the search is performed by the OS and will first the parent process' current directory before thePATHenvironment variable (see the documentation for CreateProcess for the full list).
To avoid platform-dependent behavior or any issues with how the current application was launched, it is advisable to always pass an absolute path to the executable to be launched. For auxiliary binaries shipped with the application, one can construct such a path starting with QCoreApplication::applicationDirPath(). Similarly, to explicitly run an executable that is to be found relative to the directory set with setWorkingDirectory(), use a program path starting with "./" or "../" as the case may be.
On Windows, the ".exe" suffix is not required for most uses, except those outlined in the CreateProcess documentation. Additionally, QProcess will convert the Unix-style forward slashes to Windows path backslashes for the program name. This allows code using QProcess to be written in a cross-platform manner, as shown in the examples above.
QProcess does not support directly executing Unix shell or Windows command interpreter built-in functions, such as cmd.exe's dir command or the Bourne shell's export. On Unix, even though many shell built-ins are also provided as separate executables, their behavior may differ from those implemented as built-ins. To run those commands, one should explicitly execute the interpreter with suitable options. For Unix systems, launch "/bin/sh" with two arguments: "-c" and a string with the command-line to be run. For Windows, due to the non-standard way cmd.exe parses its command-line, use setNativeArguments() (for example, "/c dir d:").
Environment variables
The QProcess API offers methods to manipulate the environment variables that the child process will see. By default, the child process will have a copy of the current process environment variables that exist at the time the start() function is called. This means that any modifications performed using qputenv() prior to that call will be reflected in the child process' environment. Note that QProcess makes no attempt to prevent race conditions with qputenv() happening in other threads, so it is recommended to avoid qputenv() after the application's initial start up.
The environment for a specific child can be modified using the processEnvironment() and setProcessEnvironment() functions, which use the QProcessEnvironment class. By default, processEnvironment() will return an object for which QProcessEnvironment::inheritsFromParent() is true. Setting an environment that does not inherit from the parent will cause QProcess to use exactly that environment for the child when it is started.
The normal scenario starts from the current environment by calling QProcessEnvironment::systemEnvironment() and then proceeds to adding, changing, or removing specific variables. The resulting variable roster can then be applied to a QProcess with setProcessEnvironment().
It is possible to remove all variables from the environment or to start from an empty environment, using the QProcessEnvironment() default constructor. This is not advisable outside of controlled and system-specific conditions, as there may be system variables that are set in the current process environment and are required for proper execution of the child process.
On Windows, QProcess will copy the current process' "PATH" and "SystemRoot" environment variables if they were unset. It is not possible to unset them completely, but it is possible to set them to empty values. Setting "PATH" to empty on Windows will likely cause the child process to fail to start.
Communicating via Channels
Processes have two predefined output channels: The standard output channel (stdout) supplies regular console output, and the standard error channel (stderr) usually supplies the errors that are printed by the process. These channels represent two separate streams of data. You can toggle between them by calling setReadChannel(). QProcess emits readyRead() when data is available on the current read channel. It also emits readyReadStandardOutput() when new standard output data is available, and when new standard error data is available, readyReadStandardError() is emitted. Instead of calling read(), readLine(), or getChar(), you can explicitly read all data from either of the two channels by calling readAllStandardOutput() or readAllStandardError().
The terminology for the channels can be misleading. Be aware that the process's output channels correspond to QProcess's read channels, whereas the process's input channels correspond to QProcess's write channels. This is because what we read using QProcess is the process's output, and what we write becomes the process's input.
QProcess can merge the two output channels, so that standard output and standard error data from the running process both use the standard output channel. Call setProcessChannelMode() with MergedChannels before starting the process to activate this feature. You also have the option of forwarding the output of the running process to the calling, main process, by passing ForwardedChannels as the argument. It is also possible to forward only one of the output channels - typically one would use ForwardedErrorChannel, but ForwardedOutputChannel also exists. Note that using channel forwarding is typically a bad idea in GUI applications - you should present errors graphically instead.
Certain processes need special environment settings in order to operate. You can set environment variables for your process by calling setProcessEnvironment(). To set a working directory, call setWorkingDirectory(). By default, processes are run in the current working directory of the calling process.
The positioning and the screen Z-order of windows belonging to GUI applications started with QProcess are controlled by the underlying windowing system. For Qt 5 applications, the positioning can be specified using the -qwindowgeometry command line option; X11 applications generally accept a -geometry command line option.
Synchronous Process API
QProcess provides a set of functions which allow it to be used without an event loop, by suspending the calling thread until certain signals are emitted:
- waitForStarted() blocks until the process has started.
- waitForReadyRead() blocks until new data is available for reading on the current read channel.
- waitForBytesWritten() blocks until one payload of data has been written to the process.
- waitForFinished() blocks until the process has finished.
Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze.
The following example runs gzip to compress the string "Qt rocks!", without an event loop:
QProcess gzip;
gzip.start("gzip", QStringList() << "-c");
if (!gzip.waitForStarted())
return false;
gzip.write("Qt rocks!");
gzip.closeWriteChannel();
if (!gzip.waitForFinished())
return false;
QByteArray result = gzip.readAll();
See also QBuffer, QFile, and QTcpSocket.
Member Function Documentation
[static] QStringList QProcess::splitCommand(QStringView command)
Splits the string command into a list of tokens, and returns the list.
Tokens with spaces can be surrounded by double quotes; three consecutive double quotes represent the quote character itself.