0

So I'm trying to have my "button" directly execute a Batch file, important here is that I don't want it to show me a dialogue and make me chose the path, which is the problem I'm having right now with the following code

  void MainWindow::on_pushButton_clicked()
    {

      QString filename=QFileDialog::getOpenFileName(
      this,
      tr("Open File"),
      "C://",
      "All files (*.*);;Text File (*.txt);;Music file (*.mp3)");
    }

I think this is probably really simple, but i can't get it, I'm not even learning c++ at the moment but my boss asked me to create something out of my scope (wants me to create a GUI for a batch file and have them interact) and I thought of this approach, which is just creating a GUI that executes it.

I've looked at this question: asked to execute an external program with Qt

but they don't talk about how the file path can directly be added into the code, or if I should even be using Qprocess and how, and if I can pass it through "clicked" function.

I'm really inexperienced, all of the code above I got with the help of the internet, but I really don't know how to program using c++ so could someone please be kind enough to show me how a file path can be added to the code, assuming it's in C:\Users\name_goes_here\Downloads

I'd really appreciate it :D

Mofi
  • 46,139
  • 17
  • 80
  • 143
skdadle
  • 155
  • 1
  • 2
  • 17
  • 1
    What's the problem with `QString filename="C:\Users\name_goes_here\Downloads";`? Another advice: don't stress yourself. If your boss asks you to do stuff out of your domain (s)he has to accept it might take a bit longer ;). – Detonar Dec 20 '17 at 08:44
  • @Detonar you will need to escape the back-slash though :) `String filename="C:\\Users\\name_goes_here\\Downloads";` but hardcoded path is rarely a good idea – ymoreau Dec 20 '17 at 08:51
  • @ymoreau right, the escape. Thanks :). sure is hard-coded bad but for rudimentary use like this i don't see any problem. This seems to be a one-use application to me. – Detonar Dec 20 '17 at 08:54

3 Answers3

1

I'd recommend using QProcess for anything "execute external program" with Qt.

You could do it like this:

void MainWindow::on_pushButton_clicked()
{
    QProcess process;
    process.start("C:/Users/name_goes_here/Downloads/yourfile.bat");
    process.waitForFinished(); // Assuming that you do want to wait for it to finish before the code execution resumes
}

Note the "/" in the path. Only Windows uses the messed up "\" for path separation, which would require you to write "C:\\Users\\.." in any string in C++ as "\" needs to be escaped.
Luckily, Qt uses "/" as the universal separator and translates it to whatever the OS needs as required. So you should just use "/" whenever working with Qt.

This is from the Qt documentation:

Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system.

And finally, if you don't know how to code in C++, shouldn't you be learning that first instead of trying to execute batch files from within a library as complex as Qt? Sounds like you're trying to do too many new things at once.

TheSHEEEP
  • 2,961
  • 2
  • 31
  • 57
  • Thanks a lot for the reply, I really appreciate it. I copied your code into my Clicked Function, but now when I click on my "open file" Button that I made, nothing happens. (I don't have any problems building it and running it) Did i miss an include maybe? Also the reason I'm doing this, is not because I'm trying to learn c++, its just something my boss asked me to do :/ – skdadle Dec 22 '17 at 07:57
  • Haha... your boss doesn't really know how programming works, does he? ;) Oh, well... If nothing happens, the first thing I'd check is if the function is being called at all (either via breakpoint or logging). If it is being called, I'd check the usual suspects (is the path actually correct, etc.). If still nothing, you'll have to bite the bullet and listen to Qprocess error signals: http://doc.qt.io/qt-5/qprocess.html#errorOccurred ... or it could also be that you indeed have to execute it via cmd.exe (as Scheff wrote). There are too many possible problem causes to give a definite answer. – TheSHEEEP Dec 23 '17 at 15:41
0

This is fairly simple merging your source and the one you linked:

void MainWindow::on_pushButton_clicked()
{
  QProcess::execute(
    QString::fromLatin1(
      "cmd.exe /c C:\\Users\\name_goes_here\\Downloads\\file.bat"));
}

Notes:

  1. I used QProcess::execute() instead of QProcess::start() to make things even simpler.

  2. To achieve execution of the batch file, I pass it to cmd32.exe as this is the interpreter which is responsible.


As MCVE testQProcessBatch.cc:

// Qt header:
#include <QtWidgets>

void on_pushButton_clicked()
{
#if 0 // WORKS:
  QProcess::execute(
    QString::fromUtf8("cmd.exe /c C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#else // WORKS AS WELL:
  QProcess::execute(
    QString::fromUtf8("C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#endif // 0
}

int main(int argc, char **argv)
{
  qDebug() << "Version:" << QT_VERSION_STR;
  // main application
  QApplication app(argc, argv);
  QMainWindow qWin;
  QPushButton qBtn(QString::fromLatin1("Start cmd"));
  qWin.setCentralWidget(&qBtn);
  qWin.show();
  QObject::connect(&qBtn, &QPushButton::clicked,
    &on_pushButton_clicked);
  // run application
  return app.exec();
}

and the test batch file testBatch.bat:

echo "This is testBatch.bat"
pause

Tested with VS2013 on Windows 10:

Snapshot of testQProcessBatch (after pressing button)

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • Don't you think this is a tad bit too much constructing and concatenating for a fairly simple use case? All those QString::fromXXX aren't really needed here, IMO. And why do a QDir.fileName, instead of just putting the string there directly? I'm also unsure about cmd32.exe being needed to execute a batch file. Would have to try it. – TheSHEEEP Dec 20 '17 at 09:01
  • @TheSHEEP About `QDir`: I just learnt it these days - may be I was a little bit over-enthusiastic... About `cmd32.exe`: Not sure - I'm just preparing an MCVE to try out. – Scheff's Cat Dec 20 '17 at 09:03
  • @TheSHEEEP You're right. It works without `cmd.exe` as well. (I had something in mind but cannot remember clearly what...) – Scheff's Cat Dec 20 '17 at 09:28
  • 1
    I would assume what happens without cmd.exe depends on the system settings. By default, the batch will be executed, but it is possible some text editor was set to open .bat files - and then that would likely happen from Qt as well. – TheSHEEEP Dec 20 '17 at 09:54
0

Thanks for contributing guys!

I tried using the QProcess method but I think I'm too inexperienced when it comes to figuring out problems associated with it (which I did face when using this method). the CMD route is probably good but I also thought it was too difficult and both of these methods didn't work for me.

Here's what I have now (thanks to Detonar and ymoreau) and and it seems to be doing the job, this might not be the most optimal approach, but it worked for me!

I included QDesktopServices and QUrl

void MainWindow::on_pushButton_clicked()
 {
      QString filename="C:\\Users\\Name_goes_here\\Downloads\\test.bat";(
      this);

      hide();  //optional

      QDesktopServices::openUrl(QUrl("file:///"+filename,QUrl::TolerantMode));
        }
skdadle
  • 155
  • 1
  • 2
  • 17