QProcess::execute capture output
-
@Jan-Willem execute() is a static method! It is not related to your QProcess instance which you connected to your slot.
You should replaceprocess.setProgram(sh);
with
process.setProgram("ls");
-
@jsulm thanks for the clarification. The I have interpreted the use of execute() wrong.
I knowprocess.setProgram("ls");
works. But I was trying to create a bash-session because of the variables defined in .bashrc.
The output of the QProcess seems to be only available after the QProcess is finished. Consider this:process.setProgram("/bin/bash"); process.start(); process.write("pwd\n"); process.write("cd ..\n"); process.write("pwd");
This gives the desired result, but the output is received only when the QProcess is finished. And then the bash-session is closed, so the result of cd is not there anymore.
You see my problem? I can't seem to find a way around it. -
What exactly do you want to do with your serie of commands ?
-
@Jan-Willem Maybe you should do
process.write("cd ..\n"); process.write("pwd");
after you got the output of the first pwd? Because currently you're flooding the shell with commands without waiting for them to finish.
-
@SGaist I'm experimenting with building a simple terminal window. The series of commands are only for testing. It could be any command for that matter.
@jsulm Thanks, I suspected that. But the output never comes, unless I close the writingchannel or what for the process to finish.If I write:
process.write("pwd\n"); process.write("ls\n"); process.write("pwd\n");
it works as expected. The output after each step is shown. cmd does not generate output, but the result is also not shown on the last call of pwd.
When I create a custom object through which the process is started and then connect it to a Q(Plain)TextEdit, then everything seems to work. I'm trying to understand the reason why.
-
Yes, but much more simple.
I have looked into that code and from a derived project QTermWidget.It seems I now have a working solution, but I try to understand why this works.
-
I have started from scratch to see what my problem actually was, but I wasn't able to reproduce it.
I probably got lost somewhere in my code.Well, below is the working code for the curious.
@SGaist @jsulm Thanks for your help!
Widget::Widget(QWidget *parent) : QWidget(parent) { QPlainTextEdit *plainTextEdit = new QPlainTextEdit(this); plainTextEdit->setReadOnly(true); QLineEdit *lineEdit = new QLineEdit(this); lineEdit->setClearButtonEnabled(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(plainTextEdit); layout->addWidget(lineEdit); setLayout(layout); connect(&process, &QProcess::readyReadStandardOutput, [=](){ plainTextEdit->appendPlainText(process.readAllStandardOutput()); }); connect(&process, &QProcess::readyReadStandardError, [=](){ plainTextEdit->appendPlainText(process.readAllStandardError()); }); connect(&process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &Widget::close); connect(lineEdit, &QLineEdit::returnPressed, [=](){ process.write(lineEdit->text().toLatin1() + "\n"); lineEdit->clear(); }); process.start("sh"); } Widget::~Widget() { process.close(); }
-
@SGaist Good one! Though I had to use the C++11 version since C++14 is still in Debian Sid.
// C++11 connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &MainWindow::close);
For those who want to know, this is the C++14-version:
// C++14 connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &MainWindow::close);
Since the actual problem of this thread is solved, I will mark this thread as solved tomorrow. In the mean time comments on the above code can be made.