diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 8409e7e479..3993cf5002 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -458,6 +458,9 @@ void QProcessPrivate::Channel::clear() 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 @@ -1946,6 +1949,58 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM return; } + d->program = program; + d->arguments = arguments; + + open(mode); +} + +/*! + \since 5.1 + \overload + + Starts the program set by setProgram() with arguments set by setArguments(). + The OpenMode is set to \a mode. + + This method is a convenient alias to open(). + + \sa open(), setProgram(), setArguments() + */ +void QProcess::start(OpenMode mode) +{ + open(mode); +} + +/*! + Starts the program set by setProgram() in a new process, if none is already + running, passing the command line arguments set by setArguments(). The OpenMode + is set to \a mode. + + The QProcess object will immediately enter the Starting state. If the + process starts successfully, QProcess will emit started(); otherwise, + error() will be emitted. If the QProcess object is already running a + process, a warning may be printed at the console, the function will return false, + and the existing process will continue running. + + \note Processes are started asynchronously, which means the started() + and error() signals may be delayed. Call waitForStarted() to make + sure the process has started (or has failed to start) and those signals + have been emitted. In this regard, a true return value merly means the process + was correcty initialized, not that the program was actually started. + +*/ +bool QProcess::open(OpenMode mode) +{ + Q_D(QProcess); + if (d->processState != NotRunning) { + qWarning("QProcess::start: Process is already running"); + return false; + } + if (d->program.isEmpty()) { + qWarning("QProcess::start: program not set"); + return false; + } + #if defined QPROCESS_DEBUG qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')'; #endif @@ -1967,14 +2022,13 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM d->stdoutChannel.closed = false; d->stderrChannel.closed = false; - d->program = program; - d->arguments = arguments; - d->exitCode = 0; d->exitStatus = NormalExit; d->processError = QProcess::UnknownError; d->errorString.clear(); d->startProcess(); + + return true; } @@ -2073,6 +2127,24 @@ QString QProcess::program() const return d->program; } +/*! + \since 5.1 + + Set the \a program to use when starting the process. + That function must be call before open() + + \sa start(), setArguments(), program() +*/ +void QProcess::setProgram(const QString &program) +{ + Q_D(QProcess); + if (d->processState != NotRunning) { + qWarning("QProcess::setProgram: Process is already running"); + return; + } + d->program = program; +} + /*! Returns the command line arguments the process was last started with. @@ -2084,6 +2156,24 @@ QStringList QProcess::arguments() const return d->arguments; } +/*! + \since 5.1 + + Set the \a arguments to pass to the called program when starting the process. + That function must be call before open() + + \sa start(), setProgram(), arguments() +*/ +void QProcess::setArguments(const QStringList &arguments) +{ + Q_D(QProcess); + if (d->processState != NotRunning) { + qWarning("QProcess::setProgram: Process is already running"); + return; + } + d->arguments = arguments; +} + /*! Attempts to terminate the process. diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index e8ebadf101..29adf37f74 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -136,8 +136,14 @@ public: void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite); void start(const QString &command, OpenMode mode = ReadWrite); + void start(OpenMode mode = ReadWrite); + bool open(OpenMode mode = ReadWrite) Q_DECL_OVERRIDE; + QString program() const; + void setProgram(const QString &program); + QStringList arguments() const; + void setArguments(const QStringList & arguments); ProcessChannelMode readChannelMode() const; void setReadChannelMode(ProcessChannelMode mode); diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 11824f4ab6..f01e319872 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -81,6 +81,7 @@ private slots: void getSetCheck(); void constructing(); void simpleStart(); + void startWithOpen(); void execute(); void startDetached(); void crashTest(); @@ -283,6 +284,25 @@ void tst_QProcess::simpleStart() QCOMPARE(qvariant_cast(spy.at(1).at(0)), QProcess::Running); QCOMPARE(qvariant_cast(spy.at(2).at(0)), QProcess::NotRunning); } + +//----------------------------------------------------------------------------- +void tst_QProcess::startWithOpen() +{ + QProcess p; + QTest::ignoreMessage(QtWarningMsg, "QProcess::start: program not set"); + QCOMPARE(p.open(QIODevice::ReadOnly), false); + + p.setProgram("testProcessNormal/testProcessNormal"); + QCOMPARE(p.program(), QString("testProcessNormal/testProcessNormal")); + + p.setArguments(QStringList() << "arg1" << "arg2"); + QCOMPARE(p.arguments().size(), 2); + + QVERIFY(p.open(QIODevice::ReadOnly)); + QCOMPARE(p.openMode(), QIODevice::ReadOnly); + QVERIFY(p.waitForFinished(5000)); +} + //----------------------------------------------------------------------------- void tst_QProcess::execute() {