8

I have a shell script which takes backup on a remote server when executed on a touchscreen PC (Uubntu Lucid Lynx). Now I want this to be automated by making a small Button in a GUI application that is running on it. The application is built using Qt and C++.

Until now, I am able to use the QFileDialog to open a folder browser and navigate to the .sh file, but is it possible to directly open the defined .sh file (i.e. by defining the name and location)?

There were some hints that QProcess should be used but I am kinda confused about its implementation.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
RicoRicochet
  • 2,249
  • 9
  • 28
  • 53

3 Answers3

8

You could make it either blocking or non-blocking. It depends on whether you would like to block your main process or run the shell script in the background in an async mode.

Also, since you do not need the output, you do not even need to instantiate here, just use the static methods.

Blocking code

#include <QString>
#include <QFileDialog>
#include <QProcess>
#include <QDebug>

...

// Get this file name dynamically with an input GUI element, like QFileDialog
// or hard code the string here.

QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Script"), "/", tr("Script Files (*.sh)"));

if (QProcess::execute(QString("/bin/sh ") + fileName) < 0)
    qDebug() << "Failed to run";

Non-blocking

#include <QString>
#include <QFileDialog>
#include <QProcess>
#include <QDebug>

...

// Get this file name dynamically with an input GUI element, like QFileDialog
// or hard code the string here.

QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Script"), "/", tr("Script Files (*.sh)"));

// Uniform initialization requires C++11 support, so you would need to put
// this into your project file: CONFIG+=c+11

if (!QProcess::startDetached("/bin/sh", QStringList{fileName}))
    qDebug() << "Failed to run";
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
László Papp
  • 51,870
  • 39
  • 111
  • 135
  • 1
    although i solved my problem, but can u tell me what is the basic difference between blocking and non-blocking ??? actually i am new in this domain... – RicoRicochet May 21 '14 at 05:15
  • no no, actually my issue was the proper execution of my shell script via push button & i was not able to find the proper coding format for QProcess, maybe cuz the qt docs are helpful but a bit too much in depth so i got a little confused. i want to know the difference (conceptual) between blocking and non-blocking... – RicoRicochet May 21 '14 at 05:24
  • I solved the issue with the proper format of QProcess, i did not know the code structure of it. I was previously working with QFileDialog to open the folder browser and manually slecting and running the program, but that was tedious. So now, i used the code snippet to execute the script when the button is clicked. void MainWindow::on_pushButton_clicked() { QProcess process; process.startDetached("/bin/sh", QStringList()<< "/path/to/my/script.sh"); } – RicoRicochet May 21 '14 at 05:33
  • @AmarjitBiswas: I would personally not suggest that code literally as I think it ignores some programming practices, but it is your choice. – László Papp May 21 '14 at 05:35
  • then ??? i followed it cuz, you know it made the ends meet... what should be the proper one then ??? going through your docs now, one thing i understood till now, for my application i should start detached. – RicoRicochet May 21 '14 at 05:44
  • @AmarjitBiswas: you are creating an object needlessly when a static method can do that without additional object. Also, QStringList() << ".." is pre C++11'ish. As for the blocking and non-blocking, it is quite simple. Blocking is blocking the process, and non-blocking does not, so it is async. It is not C++ and Qt related question, but generic functional programming. I updated the answer reflecting all this. – László Papp May 21 '14 at 07:41
5

You can run shell or bash passing your script as a parameter :

QProcess process;
process.startDetached("/bin/sh", QStringList()<< "/Path/to/myScript.sh");
Nejat
  • 31,784
  • 12
  • 106
  • 138
3

Use one of QProcess::startDetached overloads: http://qt-project.org/doc/qt-4.8/qprocess.html#startDetached. This one is the most complete:

bool QProcess::startDetached ( const QString & program, const QStringList & arguments, const QString & workingDirectory, qint64 * pid = 0 ) [static]

Usage example:

QProcess::startDetached("/.../script", QStringList { "-i", "a.txt", ... });

QStringList constructor above uses C++11 feature. You can always construct QStringList in a C++03-supported way, e.g. QStringlist list; list << "-i" << "a.txt"; Or if you do not need to pass any parameters to your script, just call QProcess::startDetached("/.../script").

If you need to receive your script's output, you can create QProcess object and call start. It is well described here: http://qt-project.org/doc/qt-4.8/qprocess.html#details

vedg
  • 785
  • 2
  • 7
  • 18