QProcess wont run python with full runtime
-
Hello friends!!! I'm new to the forum and Qt and I'm having trouble finding a solution to this problem:
Whenever I try to launch my python command, I get an empty string as a result. I have the full python runtime in this folder /record_x/record_x/python-3.10.8-embed-amd64 and I think this is important I DON'T have python set in my path. The idea is to distribute this application as a compressed file that includes the c++ executable and the whole python runtime.
connect(m_button, SIGNAL (clicked(bool)), this, SLOT (slotButtonClicked(bool))); void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "./debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "--version"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); qDebug() << process->readAll(); process->waitForFinished(); } else { m_label->setText("Please select the source folder"); } }Could anyone point me in the right direction? I've also tried setting the path with QProcessEnvironment but I don't know if I've added the correct files. Thanks.
-
Hello friends!!! I'm new to the forum and Qt and I'm having trouble finding a solution to this problem:
Whenever I try to launch my python command, I get an empty string as a result. I have the full python runtime in this folder /record_x/record_x/python-3.10.8-embed-amd64 and I think this is important I DON'T have python set in my path. The idea is to distribute this application as a compressed file that includes the c++ executable and the whole python runtime.
connect(m_button, SIGNAL (clicked(bool)), this, SLOT (slotButtonClicked(bool))); void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "./debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "--version"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); qDebug() << process->readAll(); process->waitForFinished(); } else { m_label->setText("Please select the source folder"); } }Could anyone point me in the right direction? I've also tried setting the path with QProcessEnvironment but I don't know if I've added the correct files. Thanks.
@TheGrandSinnovia
First: you're using relative path to the command - are you sure it is found at runtime?
Second: you call readAll just after starting the process. This can't work as QProcess needs some time to start the process in background. Either wait using https://doc.qt.io/qt-6/qprocess.html#waitForReadyRead or connect slots to https://doc.qt.io/qt-6/qprocess.html#readyReadStandardOutput and https://doc.qt.io/qt-6/qprocess.html#readyReadStandardError
Third: why do you allocate QProcess on the heap if you anyway implement the stuff in a synchronous way (using waitForFinished)? Since you're not deleting it you have a memory leak. -
Hello friends!!! I'm new to the forum and Qt and I'm having trouble finding a solution to this problem:
Whenever I try to launch my python command, I get an empty string as a result. I have the full python runtime in this folder /record_x/record_x/python-3.10.8-embed-amd64 and I think this is important I DON'T have python set in my path. The idea is to distribute this application as a compressed file that includes the c++ executable and the whole python runtime.
connect(m_button, SIGNAL (clicked(bool)), this, SLOT (slotButtonClicked(bool))); void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "./debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "--version"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); qDebug() << process->readAll(); process->waitForFinished(); } else { m_label->setText("Please select the source folder"); } }Could anyone point me in the right direction? I've also tried setting the path with QProcessEnvironment but I don't know if I've added the correct files. Thanks.
@TheGrandSinnovia
Everything as @jsulm says. At minimum:- Do not run commands via a relative path, as you do not know what the current directory is.
- Add error handling to code you write. For example, put a slot on
QProcess::errorOccurred(). That might be telling you it cannot run the command.... - If you do want to call
waitForFinished()(better the asynchronous calls, but still) move theprocess->readAll();to after thewaitForFinished(), not before.
-
@jsulm said in QProcess wont run python with full runtime:
aitForReadyRead
Thank you, with a few modifications i managed ro get the python version that I'm using. But now it doesen't seem to execute the python script main.py which I have provided, it does print "Hello world!" if I change the contents of main.py to:
print("Hello world")But as soon as I modify main.py to a more complex file it goes back to returning an empty string "". I have verified that my python script is working correctly by invoking python manually, it does have some imports that I have manually added to the python runtime. Here is my revised code:
void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "./debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "./debug/record_x/record_x/python-3.10.8-embed-amd64/main.py"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); process->waitForReadyRead(-1); qDebug() << process->readAll(); process->waitForFinished(-1); process->close(); } else { m_label->setText("Please select the source folder"); } }Could you help me with this as well please? The program main.py is supposed to print to the console.
-
@jsulm said in QProcess wont run python with full runtime:
aitForReadyRead
Thank you, with a few modifications i managed ro get the python version that I'm using. But now it doesen't seem to execute the python script main.py which I have provided, it does print "Hello world!" if I change the contents of main.py to:
print("Hello world")But as soon as I modify main.py to a more complex file it goes back to returning an empty string "". I have verified that my python script is working correctly by invoking python manually, it does have some imports that I have manually added to the python runtime. Here is my revised code:
void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "./debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "./debug/record_x/record_x/python-3.10.8-embed-amd64/main.py"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); process->waitForReadyRead(-1); qDebug() << process->readAll(); process->waitForFinished(-1); process->close(); } else { m_label->setText("Please select the source folder"); } }Could you help me with this as well please? The program main.py is supposed to print to the console.
@TheGrandSinnovia
We told you:- Do not use relative paths as you do not know what the current directory. Why have you ignored this and now use two relative paths?
- Move the
readAll()to after thewaitForFinished(), not before it. Do not rely onwaitForReadyRead(-1)to read all output, it may not. Why ignore this when it may well be the issue?
If you do want help there is not much point asking if you then ignore suggestions....
-
My bad I wrote the post before reading yours and I didn't see i could get valuable information. This is the revised revision of the revised code hahaha:
void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "C:/Users/alggd/OneDrive/Documentos/build-RecordX-Desktop_Qt_6_4_0_MinGW_64_bit-Debug/debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "C:/Users/alggd/OneDrive/Documentos/build-RecordX-Desktop_Qt_6_4_0_MinGW_64_bit-Debug/debug/record_x/record_x/python-3.10.8-embed-amd64/main.py"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); process->waitForFinished(-1); process->waitForReadyRead(-1); qDebug() << process->readAll(); process->close(); } else { m_label->setText("Please select the source folder"); } }Now i get this cod via terminal:
"BPD-03 (iso-8859-1)\r\n...reading\r\nBPD-05 (iso-8859-1)\r\n...reading\r\nBPD-06 (iso-8859-1)\r\n...reading\r\nBPD-07 (iso-8859-1)\r\n...reading\r\nBPD-08 (utf-8)\r\n...reading\r\nBPD-10 (iso-8859-1)\r\n...reading\r\nBPD-13 (iso-8859-1)\r\n...reading\r\nBPD-14 (utf-8)\r\n...reading\r\nBPD-15 (utf-8)\r\n...reading\r\nBPD-16 (iso-8859-1)\r\n...reading\r\nBPD-17 (utf-8)\r\n...reading\r\nBPD-18 (utf-8)\r\n...reading\r\nBPD-20 (iso-8859-1)Do i have to specify an encoding or something of the sort. Sorry for the newbie questions but qt is so well documented I thought it would be a great place to start.
-
My bad I wrote the post before reading yours and I didn't see i could get valuable information. This is the revised revision of the revised code hahaha:
void Window::slotButtonClicked(bool checked) { if (checked) { // path_from = QFileDialog::getExistingDirectory(this, "Open source directory", QDir::currentPath()); // m_label->setText(path_from); QString command = "C:/Users/alggd/OneDrive/Documentos/build-RecordX-Desktop_Qt_6_4_0_MinGW_64_bit-Debug/debug/record_x/record_x/python-3.10.8-embed-amd64/python"; QStringList arguments; arguments << "C:/Users/alggd/OneDrive/Documentos/build-RecordX-Desktop_Qt_6_4_0_MinGW_64_bit-Debug/debug/record_x/record_x/python-3.10.8-embed-amd64/main.py"; //<< path_from; QProcess *process = new QProcess(this); process->start(command, arguments); process->waitForFinished(-1); process->waitForReadyRead(-1); qDebug() << process->readAll(); process->close(); } else { m_label->setText("Please select the source folder"); } }Now i get this cod via terminal:
"BPD-03 (iso-8859-1)\r\n...reading\r\nBPD-05 (iso-8859-1)\r\n...reading\r\nBPD-06 (iso-8859-1)\r\n...reading\r\nBPD-07 (iso-8859-1)\r\n...reading\r\nBPD-08 (utf-8)\r\n...reading\r\nBPD-10 (iso-8859-1)\r\n...reading\r\nBPD-13 (iso-8859-1)\r\n...reading\r\nBPD-14 (utf-8)\r\n...reading\r\nBPD-15 (utf-8)\r\n...reading\r\nBPD-16 (iso-8859-1)\r\n...reading\r\nBPD-17 (utf-8)\r\n...reading\r\nBPD-18 (utf-8)\r\n...reading\r\nBPD-20 (iso-8859-1)Do i have to specify an encoding or something of the sort. Sorry for the newbie questions but qt is so well documented I thought it would be a great place to start.
@TheGrandSinnovia said in QProcess wont run python with full runtime:
Do i have to specify an encoding or something of the sort.
Why are you saying this? I see a bunch of textual output --- presumably just what the Python script is supposed to output --- so what is the problem with it?
-
@TheGrandSinnovia said in QProcess wont run python with full runtime:
Do i have to specify an encoding or something of the sort.
Why are you saying this? I see a bunch of textual output --- presumably just what the Python script is supposed to output --- so what is the problem with it?
@JonB
I see it was confusing at first to see a mix of iso-8859-1 and I didn't understand it. I'll mark it as solved, but I have a final question. Say I want to share this program with a friend. My friend doesen't have the same project structure as me, which is to say that he has different folders. Would it be ok in that case to use relative paths to a specific file so that the project works as is in his computer? Thank you very much for your help and espcially for the speed of your answers. -
@JonB
I see it was confusing at first to see a mix of iso-8859-1 and I didn't understand it. I'll mark it as solved, but I have a final question. Say I want to share this program with a friend. My friend doesen't have the same project structure as me, which is to say that he has different folders. Would it be ok in that case to use relative paths to a specific file so that the project works as is in his computer? Thank you very much for your help and espcially for the speed of your answers.@TheGrandSinnovia said in QProcess wont run python with full runtime:
I see it was confusing at first to see a mix of iso-8859-1 and I didn't understand it.
I asked you whether this is the output you get when you run the Python script directly --- is it? I do not know what that
main.pyPython script is supposed to output, only you do.... If it is different there is an issue, if it is the same then what is there to say other than it is correct?No you ought never use relative paths for, say, launching the python executable
./debug/record_x/record_x/python-3.10.8-embed-amd64/pythonsince you do not know what his
.directory will be.You have two choices:
-
You could instruct your other user that before launching your Qt application he must open a terminal and
cdto the right directory for this to work for him and then invoke your Qt executable. Possible but "flaky". -
Clearly you must not use an absolute path of
C:/Users/alggd/OneDrive/...if that is not correct for him. Instead you must place thepythonexecutable somewhere and construct an absolute path based on that. The most obvious would be to locate it relative to where your Qt program's executable, such as in the same directory or (perhaps better) in some sub-directory from there. Then you can use QCoreApplication::applicationDirPath() to build the correct absolute path.
Alternatively you might look at Qt's QStandardPaths and put your
pythonexecutable somewhere suitable for one of those. -
-
@TheGrandSinnovia said in QProcess wont run python with full runtime:
I see it was confusing at first to see a mix of iso-8859-1 and I didn't understand it.
I asked you whether this is the output you get when you run the Python script directly --- is it? I do not know what that
main.pyPython script is supposed to output, only you do.... If it is different there is an issue, if it is the same then what is there to say other than it is correct?No you ought never use relative paths for, say, launching the python executable
./debug/record_x/record_x/python-3.10.8-embed-amd64/pythonsince you do not know what his
.directory will be.You have two choices:
-
You could instruct your other user that before launching your Qt application he must open a terminal and
cdto the right directory for this to work for him and then invoke your Qt executable. Possible but "flaky". -
Clearly you must not use an absolute path of
C:/Users/alggd/OneDrive/...if that is not correct for him. Instead you must place thepythonexecutable somewhere and construct an absolute path based on that. The most obvious would be to locate it relative to where your Qt program's executable, such as in the same directory or (perhaps better) in some sub-directory from there. Then you can use QCoreApplication::applicationDirPath() to build the correct absolute path.
Alternatively you might look at Qt's QStandardPaths and put your
pythonexecutable somewhere suitable for one of those.@JonB
Perfect, thank you! I will look into that, this was a lot of progress for today, the python program seems to get stuck at some point thats why I was wondering what happened. Thanks again. It certainly is strange becouse when i run it manually no problem arises, and now we know for sure its running but when run by a process it gets stuck. UPDATE: Code wasn't getting stuck, it was a human error on my side, as it most often is, thank you for your patience. -