QIODevice::read (QProcess): device not open
-
Hello guys !
I'm working on QtCreator and I want to use a python script with a xml file from QT Windows.
The file is open, but I can't use the script :
QString p_stdout = _process.readAll();
show me : QIODevice::read (QProcess): device not open
Here is my code :
// EXEC PYTHON SCRIPT QStringList args = (QStringList() << script_path << employesDesires << file_path) ; // parameters QString program = "Python"; // program int exitCode = _process.execute( program, args ); _process.waitForFinished(-1); // _process.open(QIODevice::OpenMode()) ; QString p_stdout = _process.readAll(); QString s = QString::number(exitCode); ui->labelResult->setText(s);
exitCode return 0
I searched on many forums but can't find a solution that I can understand..Someone have an idea ?
-
@FoxBandyKoot
http://doc.qt.io/qt-5/qprocess.html#execute isstatic
. It is supposed to be invoked viaQProcess::execute()
. You do not even show your declaration of_process
, but assuming it's aQProcess
instance you cannot use it to access anything from the static call.You need to use the member function http://doc.qt.io/qt-5/qprocess.html#start on your
QProcess
instance. -
Okey I don't know static notion, but I will try start() function.
QProcess _process;
Yes it is a Qprocess instance ! :)
Thanks you for help me !
-
So I tried many things since the last time...
I do not have the error anymore, but I can not recover the data from my python scrypt which processes an excel file.That's where I am, I do not understand how to use signals despite the documentation...
.h file simplified
namespace Ui { class TabtStatEmp_CountWorkTogether; } class TabtStatEmp_CountWorkTogether : public QDialog { Q_OBJECT public: // constructor explicit TabtStatEmp_CountWorkTogether(QString file_path, QString script_path, QString employesDesires, QWidget *parent = nullptr); //functions QString OpenFile(); QProcess::ProcessChannel StandardOutput; void setReadChannel(QProcess::ProcessChannel StandardOutput); private: Ui::TabtStatEmp_CountWorkTogether *ui; QProcess _process; };
My .cpp simplified :
TabtStatEmp_CountWorkTogether::TabtStatEmp_CountWorkTogether(QString file_path, QString script_path, QString employesDesires, QWidget *parent) : QDialog(parent), ui(new Ui::TabtStatEmp_CountWorkTogether) { ui->setupUi(this); // OPEN XLS FILE QFile xslFile(file_path); QString test ; xslFile.open(QIODevice::ReadOnly | QIODevice::Text); // EXEC PYTHON SCRIPT QStringList args = (QStringList() << script_path << employesDesires << file_path) ; // parameters // QStringList args = (QStringList() << employesDesires ) ; // parameters QString program = "Python"; // program _process.start(program, args ); // _process.readAllStandardOutput(); _process.setReadChannel(StandardOutput); QString p_stdout = _process.readAllStandardOutput(); // get output ui->labelResult->setText(p_stdout); // display output }
It is a simplified version where the python script know already path of xml file.
And the python script return :
# version with 1 parameter def __main__(employesChoisis): total = Tabstats(employesChoisis) str(total) return total
-
Hi,
That's because you're not waiting for your process to finish. See the Synchronous Process API part of QProcess's documentation.
-
So I used your link to place signals. Program start but now I have this error in debbuging mode :
This my code :
// OPEN XLS FILE QFile xslFile(file_path); xslFile.open(QIODevice::ReadOnly | QIODevice::Text); // EXEC PYTHON SCRIPT // QStringList args = (QStringList() << script_path << employesDesires << file_path) ; // parameters QStringList args = (QStringList() << script_path << employesDesires ) ; // parameters QString program = "Python"; // program QByteArray p_stdout; _process.start(program, args ); // START PROG if (_process.waitForStarted()){ // Check if python is running QMessageBox::warning(this,tr("A COMMENCE"), tr("A COMMENCE")); _process.setReadChannel(StandardOutput); // OPEN CHANNEL FOR READ p_stdout = _process.readAllStandardOutput(); // get output } _process.closeReadChannel(StandardOutput); // Stop read QMessageBox::warning(this,tr("A FINIT"), tr("A FINIT")); // QString AA = QString::QByteArray(p_stdout[0]); // Doesn't exist ui->labelResult->setText(p_stdout); // display output if (!_process.waitForFinished()){ // If process crash, stop it return; }
This error happens when the following instruction is running :
p_stdout = _process.readAllStandardOutput(); // get output
-
Can you run your application through the debugger to get more details about what is happening ?
-
I'm not sure about what you wanna see, so I take so captures :
BREAK POINT 1
BREAK POINT 2
AFTER BREAK POINT 2
-
What does the script you launch do ?
-
It makes a count of how many times employes choosed have worked together, based on a xlsx file. Finally return this number (that I cast to string before)
Sorry for faults, I'm not english :/ And thanks you really for taking time to help me ^^
# version with 1 parameter def __main__(employesChoisis): total = Tabstats(employesChoisis) str(total) return total
-
Finally return this number (that I cast to string before)
This may not be relevant to whatever your problem is, but:
total = Tabstats(employesChoisis) str(total) return total
This does not "cast the string before returning as a result". Python
str()
is a function returning a string. It does not change its argument. Your standalonestr(total)
line has no side-effects. Your function returns whatever type is returned fromTabstats()
. If you need to force-convert return result to a string:return str(total)
. -
Do you have the same problem if you run a dummy python application ?
-
And if you just start a normal command line tool like
dir
? -
@FoxBandyKoot
The problem is what I see in the debugger output window is happening while you try to run/debug your program, right? You could put messages in/tell us where exactly you receive the warnings as you step through the code....Right, I am now peering at the screenshot code you are using.
- Remove/comment out
_process.setReadChannel(StandardOutput); // OPEN CHANNEL FOR READ _process.closeReadChannel(StandardOutput); // Stop read
I am hoping that will get rid of the nasty output?
- Your parent program is intended to read whatever the sub-process sends to its stdout. Yours is sending nothing. You cannot "return a string" like
"TEST"
from any program, Python or otherwise (you can only return an integer). Yourtest.py
should probably be goingprint("HELLO")
(Python 3), for what you want.
-
@SGaist
I tried to launch "dir" but nothing is happening@JonB
Yes that's it, when I debug I can see this error, on instruction readAllStandardOutput();
And the application crash...If I'm not in debug mode, program continues... that's really weird
And when this instruction happens :ui->labelResult->setText(p_stdout); // display output
Nothing appears. I don't understand why I should comment out functions which open and close channels... My true script return henceforth a integer :
You want me to show you the code that precedes the script?
-
I tried to launch "dir" but nothing is happening
How do you know "nothing is happening" from such a command? Since you're not collecting the output, what do you expect to see?
I don't understand why I should comment out functions which open and close channels...
Because I don't think you want them, and I don't think it should be done that way, period. I've never used it and had no problems. Why not try?
_process.readAllStandardOutput()
this function returns all data available from the standard output of the process
Since you have only done
_process.waitForStarted()
, how do you know there is any output yet available to read? -
-
I thinked that I could see content of directory where the script is located in the pyzo interpreter :
-
So I tried to comment out these functions :
_process.setReadChannel(StandardOutput); // OPEN CHANNEL FOR READ _process.closeReadChannel(StandardOutput); // Stop read
And the application doesn't crash anymore either in debug mode or not ! But the return value in "p_stdout" is null.
- how do you know there is any output yet available to read?
In my new code I try to implement
waitForReadyRead and waitForBytesWritten but I don't pass into these functions, I don't know why :/
Only waitForStarted return true, so the first readAllStandardOutput happens but return nothing from true script or test script.
#include "ui_tabtstatemp_countworktogether.h" #include <QMessageBox> #include <QDebug> TabtStatEmp_CountWorkTogether::TabtStatEmp_CountWorkTogether(QString file_path, QString script_path, QString employesDesires, QWidget *parent) : QDialog(parent), ui(new Ui::TabtStatEmp_CountWorkTogether) { ui->setupUi(this); // OPEN XLS FILE QFile xslFile(file_path); xslFile.open(QIODevice::ReadOnly | QIODevice::Text); // EXEC PYTHON SCRIPT // QStringList args = (QStringList() << script_path << employesDesires << file_path) ; // parameters on final version // QStringList args = (QStringList() << script_path << employesDesires ) ; // second try with just one parameter QStringList args = (QStringList() << script_path << employesDesires ) ; // first try without parameter QString program = "Python"; // program QString p_stdout; _process.start(program, args ); // START PROG if (_process.waitForStarted()){ // Check if python is running QMessageBox::warning(this,tr("Have started"), tr("Have started")); // _process.setReadChannel(StandardOutput); // OPEN CHANNEL FOR READ p_stdout = _process.readAllStandardOutput(); // get output if (_process.waitForReadyRead(10000)){ // 10 sec to check if data is ready QMessageBox::warning(this,tr("Data ready"), tr("Data ready")); p_stdout = _process.readAllStandardOutput(); // get output if (_process.waitForBytesWritten(10000)){ // 10 sec to check if data is written QMessageBox::warning(this,tr("Data written"), tr("Data written")); } } } // _process.closeReadChannel(StandardOutput); // CLOSE CHANNEL FOR READ QMessageBox::warning(this,tr("Have ended"), tr("Have ended")); ui->labelResult->setText(p_stdout); // display output if (!_process.waitForFinished()){ // If process crash, stop it return; } } // DESTRUCTOR TabtStatEmp_CountWorkTogether::~TabtStatEmp_CountWorkTogether() { delete ui; }
-
-
**My first problem has been resolved, so I will close this, and open a topic for my new problem.
For future people who come to this topic : The solution for "Device not open" was to use "start function" instead of "execute function".
Thank you people for helping me.**