QProcess output with adb always empty - qt

I am starting a QProcess to get e.g. the return of "adb devices".
There is no error and always an empty response. I have adb in my system env on Windows and the command runs fine on cmd.
Am I doing anythin wrong or is there another way to run adb commands in QT?
class ADBInfo: public QObject {
public:
void start(){
process = new QProcess( this );
process->start("adb.exe devices");
process->waitForFinished(-1);
qDebug() << "output: " << process->readAll();
qDebug() << "error: " << process->readAllStandardError();
}
private:
QProcess *process;
};

here is the correct way
QString mainwindow::cmd(const QString &command)
{
qDebug () << "command = "+command;
QProcess P2;
P2.start(command);
P2.waitForFinished(-1);
P2.setReadChannel(QProcess::StandardOutput);
QTextStream reade2(&P2);
QString line2,line,Out;
while (reade2.readLineInto(&line2))
Out.append(line2 +'\n');
P2.setReadChannel(QProcess::StandardError);
QTextStream reader(&P2);
while (reader.readLineInto(&line))
Out.append(line +'\n');
P2.close();
return Out.trimmed();
}
when you need to excute command
QString Result = cmd("adb devices")

Related

QProcess does not emit finished signal

I try to read out the output of a command executed in QProcess. I don't get the connection working between QProcess's finished signal and a finished handler.
I tried several different ways of connecting to QProcess finished signal but no luck so far. I know that the process executes because it prints the output in the GUI's console and that the process finishes because it passes the waitForFinished method from sequential API.
Why does my code not hit onFinish or onFinishNoPams?
header:
class Test : public QObject
{
Q_OBJECT
public:
Test(QObject *parent = 0);
Q_INVOKABLE void read();
public slots:
void onFinish(int exitCode , QProcess::ExitStatus exitStatus);
void onFinishNoPams();
private:
QProcess *m_process;
};
cpp:
Test::Test(QObject *parent)
: QObject(parent)
{}
void Test::read(){
m_process=new QProcess(this);
connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinishNoPams()));
connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus){
qDebug() << "not reached";
});
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this,&Test::onFinish);
QString program = "lsusb";
QStringList arguments;
m_process->execute(program,arguments);
m_process->waitForFinished();
qDebug() << "reached";
return;
}
void Test::onFinish(int exitCode , QProcess::ExitStatus exitStatus){
qDebug() << "not reached";
}
void Test::onFinishNoPams(){
qDebug() << "not reached";
QByteArray out=m_process->readAllStandardOutput();
}
qml:
import test 1.0
Window {
Test{
id:test
Component.onCompleted: test.read()
}
}
QProcess::execute() is a static method that starts the external process and waits for its completion in a blocking way. It has nothing to do with your m_process variable. What you want to use is QProcess::start().

QProcess ReadAllStandardError()

I need to connect a QProcess to an error handler, but I'm unsure how to pass the error string to the slot. What's below compiles, but doesn't work.
QString MainWindow::RunProcess(QString cstring)
{
QProcess *process = new QProcess(this);
connect(process,SIGNAL(readyReadStandardError()),this,SLOT( adberror(process::ReadAllStandardError() ) ))
process->start(cstring);
}
void MainWindow::adberror(QString errtxt)
{
qDebug() << "error handler";
qDebug() << errtxt;
}
I can induce a a process error, but adberror() never triggers.
When run, in the Application Output pane I see:
QObject::connect: No such slot MainWindow::adberror(process::ReadAllStandardError() )
QObject::connect: (receiver name: 'MainWindow')
edit: this is Qt 5.6. I did a new qmake/clean.
you have two options
1- wait before reading the output
QString MainWindow::RunProcess(QString cstring)
{
QProcess process;
process.start(cstring);
process.waitForFinished();
QString str = process.readAllStandardOutput();
}
2- make you process a member variable and remove your 1st argument from adberror. So,
in RunProcess
connect(process,SIGNAL(readyReadStandardError()),this,SLOT(adberror()))
then in adberror
QString str = process->readAllStandardOutput();
note that in your code you have a problem since your signal and slot args don't to match .. Also, ReadAllStandardError is not going to be ready anyways !
Edit: more code for the 2nd solution
mainwindow.h
class MainWindow
{
private://methods
void adberror();
private://attributes
QProcess* process;
};
mainwindow.cpp
QString MainWindow::RunProcess(QString cstring)
{
process = new QProcess(this);
connect(process,SIGNAL(readyReadStandardError()),this,SLOT(adberror()));
connect(process, SIGNAL(finished(int)), process, SLOT(deleteLater()));
process->start(cstring);
}
void MainWindow::adberror()
{
QString str = process->readAllStandardOutput();
qDebug() << str;
}
To process the readyReadStandardError() signal you should define the slot as:
private slots:
void adberror();
and use it:
connect(process,SIGNAL(readyReadStandardError()),this,SLOT( adberror() ));
i.e. with no arguments. Keep child process as a field of your MainWindow class to read data when it will be available.

Read output of multiple write in QProcess one by one

Can anyone help me read the output of qprocess after write and loop until all task is done?
I have this code
wifi->write("scan\n");
wifi->closeWriteChannel();
wifi->waitForBytesWritten(100);
wifi->waitForReadyRead(100);
wifi->waitForFinished(100);
qDebug() << "read output" << wifi->readAllStandardOutput();
wifi->write("scan\n");
wifi->closeWriteChannel();
wifi->waitForBytesWritten(100);
wifi->waitForReadyRead(100);
wifi->waitForFinished(100);
qDebug() << "read output" << wifi->readAllStandardOutput();
the expected output must be
"OK"
"scan results"
but the ouput is
"OK"
""
thanks.
Your multiple waits are not useful for anything. All you care about is when the process finishes, so have a single waitForFinished call with a much longer timeout (those scans don't happen in ~100ms, a few seconds is a good minimum).
You should not be using the blocking waitForXxx methods. They trip up everyone and are a source of unending grief. Forget that they exist. Use process's signals to react to events as they happen.
Qt 5 + C++11
This is the way forward. This is why you should insist on using a modern development environment, if you can. It's less typing and easier to understand.
void MyObject::startWifi() {
auto process = new QProcess(this);
process->start("program", QStringList() << "argument");
connect(process, &QProcess::started, [process]{
process->write("scan\n");
process->closeWriteChannel();
});
connect(process, &QProcess::finished, [process]{
qDebug() << process->readAllStandardOutput();
process->deleteLater();
});
}
Qt 4
class MyObject : public QObject {
Q_OBJECT
QProcess m_wifi;
Q_SLOT void onStarted() {
m_wifi.write("scan\n");
m_wifi.closeWriteChannel();
}
Q_SLOT void onFinished() {
qDebug() << m_wifi.readAllStandardOutput();
}
public:
MyObject(QObject * parent = 0) : QObject(parent) {
connect(&m_wifi, SIGNAL(started()), SLOT(onStarted()));
connect(&m_wifi, SIGNAL(finished(int,QProcess::ExitStatus)),
SLOT(onFinished()));
}
Q_SLOT void start() {
m_wifi.start("program", QStringList() << "argument");
}
};
Then invoke the start method/slot on an instance of this object. That's all.

How to use terminal commands on qt

I am QT for a project and I want to compile and run few C++ codes on QT. I have written the following code to compile a C++ file. But I don't know how to check if the program was compiled properly. If once the program has compiled, how do I run it in a terminal?
The revised code:
void MainWindow::on_actionComplile_triggered()
{
QProcess compile;
compile.setWorkingDirectory("/home");
compile.setReadChannel(QProcess::StandardOutput);
compile.setProcessChannelMode(QProcess::MergedChannels);
QTextStream out(stdout);
compile.start("gnome-terminal");
compile.write("ls"); //these lines do not get printed.
compile.waitForReadyRead();
compile.waitForFinished(-1);
QByteArray msg = compile.readAll();
out << msg.data() << endl;
}
I Found the Solution:
void MainWindow::on_actionComplile_triggered()
{
QProcess compile;
compile.setWorkingDirectory("/home/royal");
compile.setReadChannel(QProcess::StandardOutput);
compile.setProcessChannelMode(QProcess::MergedChannels);
QTextStream out(stdout);
compile.start("g++",QStringList() << "tes.cpp" << "-o" << "test");
compile.waitForFinished(-1);
QByteArray msg = compile.readAllStandardOutput();
if(msg.isEmpty())
{
qDebug() << "Successful";
}
else qDebug() << "Failed";
}

QProcess exits before complete

I've got some code that starts mencoder in a QProcess, converts a video while displaying a progress bar, then exits. The problem is, mencoder always exits before it's actually finished. The loop runs through a few times, and then closes. If I comment out the line that updates the progress bar (progress.setValue()), mencoder runs to completion and exits happily.
Been at this for a day, and can't figure it out! Also, I should mention I'm on a Mac.
Any ideas?
Thanks
Marlon
void MainWindow::convertVideo()
{
QString input_filename = "/var/input.avi";
QString output_filename = "/var/output.264";
QStringList arguments;
arguments << input_filename << "-nosound" << "-of" << "rawvideo" << "-ofps" << "30" << "-vf" << "harddup" << "-ovc" << "x264" << "-x264encopts" << "bframes=0" << "-o" << output_filename;
QProcess* myProcess = new QProcess(this);
myProcess->setReadChannel(QProcess::StandardOutput);
myProcess->start("/opt/local/bin/mencoder", arguments);
QString output_string;
QStringList output_pieces;
QProgressDialog progress("Converting video...", "Abort", 0, 100, this);
progress.setWindowModality(Qt::WindowModal);
progress.setValue(0);
progress.show();
while(myProcess->state() != QProcess::NotRunning)
{
output_string = myProcess->readAllStandardOutput();
output_pieces = output_string.split(" ");
QStringList width_string_list = output_pieces.filter("%)");
if(width_string_list.length() > 0)
{
width_string_list = width_string_list[width_string_list.length() - 1].split("(");
if(width_string_list.length() > 1)
{
width_string_list = width_string_list[1].split("%");
}
else
{
width_string_list = width_string_list[0].split("%");
}
progress.setValue(width_string_list[0].toInt());
qDebug() << width_string_list[0].toInt();
}
myProcess->waitForReadyRead();
}
return;
}
I think the QProcess timeouts before it finishes its job. Adding a myProcess->waitForFinished(-1) might help. Then your process wont timeout.

Resources