Trouble Running Python Script in Qt - Using QRC Resources
-
Hello everyone,
I'm facing an issue while trying to run a Python script in a Qt application written in C++. When I provide the path to the script directly, like this:
void Widget::on_EncryptButton_clicked() { QProcess process; QStringList arguments; arguments << "C:/Users/veltr/Desktop/Cipher_BytesHelper/script.py" <<ui->InputEncryptLineEdit->text() <<ui->KeyLineEdit->text(); process.start("python", arguments); (...)
Everything works perfectly, and the script executes as expected. However, I encountered a problem when I added the Python script to the QRC (Qt Resource Collection) file and tried to reference it using "://script.py":
void Widget::on_EncryptButton_clicked() { QProcess process; QStringList arguments; arguments << "://script.py" <<ui->InputEncryptLineEdit->text() <<ui->KeyLineEdit->text(); process.start("python", arguments); (...)
In this case, the script doesn't run, and nothing happens.The reason I need the script to be included as a resource is that I want to deploy my application on Windows. Having the script as a resource would allow me to package it along with the application without worrying about file paths.
I have already verified that the script.py file is indeed added to the QRC and compiled into the application. However, when I try to run it using the resource path, it fails.
I would greatly appreciate any insights or suggestions on how to make this work. Has anyone encountered a similar issue with running Python scripts from Qt resources? How can I ensure that the script is executed correctly when using the QRC path?
Thank you for your help!!
-
@Veltroniv You can't execute a Python script which is inside a resource file using QProcess. This is not possible because operating system needs the file somewhere in the filesystem to be able to execute it. You will have to copy the script to some location in the file system and start it from there.
-
@jsulm said in Trouble Running Python Script in Qt - Using QRC Resources:
You can't execute a Python script which is inside a resource file using QProcess. This is not possible because operating system needs the file somewhere in the filesystem to be able to execute it. You will have to copy the script to some location in the file system and start it from there.
Is it possible to achieve the desired outcome without using QProcess and instead simply copying the Python script into the built directory with windeployqt? Should I specify the path to that file before copying, am i right ?
-
@Veltroniv Not sure what QProcess has to do with deployment? Whether you put the script into a resource file or you deploy it together with the rest of the application - you still have to execute the script, right?
An alternative would be to embed Python interpreter into your application. This has two advantages: the machine where your app is running does not have to have Python installed and you can put your Python script into a resource file. Take a look at https://docs.python.org/3/extending/embedding.html -
@jsulm said in Trouble Running Python Script in Qt - Using QRC Resources:
@Veltroniv Not sure what QProcess has to do with deployment? Whether you put the script into a resource file or you deploy it together with the rest of the application - you still have to execute the script, right?
That's right.
An alternative would be to embed Python interpreter into your application. This has two advantages: the machine where your app is running does not have to have Python installed and you can put your Python script into a resource file. Take a look at https://docs.python.org/3/extending/embedding.html
I don't know if I'm skilled enough to go into such details, but the fact that the machine where my app will be running does not need to have python installed is kinda interesting.
##EDIT
i have Python installed and it is in the system path, but my QT Creator still cannot find #include <Python.h>. I dont know if i'm doing smth wrong. -
As mentioned before you need to copy the script file so Python can find it. One good approach is too use QTemporaryFile. Sometimes I just use it to give a unique file name, then close it and I can use a regular QFile::copy() after that.
-
Storing a python script in qrc can work by feeding it to the python interpreter via standard input, presuming that the script doesn't need stdin for other input. That saves writing out a temporary file, which may or may not be worth the effort.
The basic idea is:
QFile *script; QProcess *process; [...] connect(process, &QProcess::started, [script, process]() { process->write(script->readAll()); } );
This should work on macOS and Linux. I'm less confident about Windows, where CPython handles the standard file descriptors differently.
-
Well, I finally did it by using a different approach.
I built an .exe file from my .py file with all the dependencies (included libraries etc...). The whole dirr (With exe file created from .py) packed into the QT built dirr.
The next step was gathering the path to exe file, then with some string transform, get the path to my script. And done, work perfectly. Don't need to install py interpreter on different machines. -
I built an .exe file from my .py file with all the dependencies (included libraries etc...).
I presume you mean that whatever tool you used to generate a
.exe
from the.py
source embeds a standalone Python interpreter into that executable, so no external Python is needed?And, just checking, what did you use to "gathering the path to exe file"? I assume you mean to the top-level executable of your Qt application, and then you locate the other executable generated from the Python script because you know it's relative to where your top-level executable will be installed?
-
@JonB said in Trouble Running Python Script in Qt - Using QRC Resources:
I built an .exe file from my .py file with all the dependencies (included libraries etc...).
I presume you mean that whatever tool you used to generate a
.exe
from the.py
source embeds a standalone Python interpreter into that executable, so no external Python is needed?yes, i guess. Its working properly so...
And, just checking, what did you use to "gathering the path to exe file"? I assume you mean to the top-level executable of your Qt application, and then you locate the other executable generated from the Python script because you know it's relative to where your top-level executable will be installed?
Yess, thats correct. It might not have been clear.