QProcess не выполняет скрипт Python

Я пытаюсь выполнить процесс в Qt (в Linux), который выполняет скрипт Python, и мне не удалось заставить его работать. Это код:

QProcess process;
QString scriptFile = "../../scriptPath/script.py";

QString pyCommand = "\"python " + scriptFile + 
                    " -f " + parameter1 +
                    " -t parameter2" +
                    " -v parameter3" +
                    " -e " + parameter4 + "\"";

printf("PyCommand: %s\n", qStringToStdString(pyCommand).c_str());

process.start ("bash", QStringList () << "-c" << pyCommand);

Где parameter1 и parameter3 — это строки QString, которые я получаю из файловых диалогов (оба пути верны), а parameter2 и parameter4 — жестко заданные строки (на всякий случай в этих строках есть символы «-» и «.»). Функция qStringToStdString — это функция, которую я создал для преобразования QString в std::string, и она отлично работает (я уже использовал ее).

PyCommand печатается в консоли и выглядит нормально. На самом деле, если я открою терминал и попытаюсь выполнить bash -c, а затем то, что я получаю в инструкции printf, это сработает. Но это не работает, когда я запускаю приложение Qt.

Может ли кто-нибудь помочь мне здесь? Что-то я упускаю?


person Carlos Pastor    schedule 04.10.2013    source источник


Ответы (3)


Ваш код игнорирует то, как API был разработан для работы. Вы должны использовать любую из альтернатив, представленных ниже. Использование интерпретатора python явно зависит от того, правильно ли вы используете shebang в своем скрипте Python. Я привел его только для справки, но вы легко можете от него избавиться. Здесь не в этом суть вашего вопроса.

Первый вариант (на основе QStringList)

QProcess process;
QString scriptFile =  QCoreApplication::applicationDirPath() + "../../scriptPath/script.py";

QStringList pythonCommandArguments = QStringList() << scriptFile
    << "-f " << parameter1 << "-t" <<  parameter2 << "-v"
    <<  parameter3 << "-e" << parameter4;

printf("PyCommand: %s\n", qStringToStdString(pythonCommandArguments.join(' ')).c_str());

process.start ("python", pythonCommandArguments);

Второй вариант (на основе QString)

QProcess process;
QString scriptFile =  QCoreApplication::applicationDirPath() + "../../scriptPath/script.py";

QString pythonCommand = "python " + scriptFile + 
                    " -f " + parameter1 +
                    " -t parameter2" +
                    " -v parameter3" +
                    " -e " + parameter4;

printf("PyCommand: %s\n", qStringToStdString(pythonCommand).c_str());

process.start (pythonCommand);

Здесь вы можете найти правильные сигнатуры методов для обоих способов:

  • void QProcess::start(const QString & program, const QStringList & arguments, OpenMode mode = ReadWrite)

http://doc.qt.io/qt-5/qprocess.html#start

  • void QProcess::start(const QString & command, OpenMode mode = ReadWrite)

http://doc.qt.io/qt-5/qprocess.html#start-3

person lpapp    schedule 04.10.2013

Вам нужно использовать QStringList() для параметра командной строки.

Ваш pyCommand должен быть QStringList.

Что-то вроде этого:

QStringList pyCommand;
pyCommand << "-f" << parameter1 <<
                "-t" << parameter2 <<
                "-v" << parameter3 <<
                "-e" << parameter4;

process.start(scriptFile, pyCommand);

См. документы: http://doc.qt.io/qt-5/qprocess.html#start

person yegorich    schedule 04.10.2013

Так что в итоге у меня все заработало. Как прокомментировал Ласло, способ его выполнения заключается в запуске процесса с python и передаче всех аргументов как QStringList. Это то, что я пробовал в начале, и это вообще не сработало. Поэтому я искал информацию в Интернете и увидел, что многие люди выполняли процесс bash, а затем передавали строку с помощью команды python вместо того, чтобы делать это, как я. Я пытался сделать так, но тоже не получилось...

Решение? Что ж, я сделал то, что должен был сделать, прежде чем задавать вопрос здесь. Я связал наиболее важные сигналы процесса (начало, завершение и ошибка) с некоторыми простыми методами, записывающими вывод. В конце концов я узнал, что python возвращает 2 (Нет такого файла или каталога) как exitCode.

Похоже, что приложение не использовало путь к исполняемому файлу в качестве корневого пути, и поэтому путь, на который я ссылался ("../../scriptPath/script.py"), не существовал. Чтобы получить правильный двоичный путь, я использую сейчас QDir::currentPath() + "/scriptPath/script.py".

person Carlos Pastor    schedule 07.10.2013
comment
Нет, используйте QCoreApplication::applicationDirPath() вместо QDir::currentPath(), как я упоминал в своем посте. Я бы предложил еще раз вернуться к моему ответу. Вероятно, это не лучший ответ для принятия, но я оставлю его вам. - person lpapp; 19.10.2013