0

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.

Alan
  • 1,265
  • 4
  • 22
  • 44
  • first, your signal and slot args have to match .. second, ReadAllStandardError is not going to be ready anyways ! – HazemGomaa Nov 23 '16 at 20:50

2 Answers2

0

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.

Nikita
  • 6,270
  • 2
  • 24
  • 37
  • What do you mean by "Keep child process as a field of your MainWindow class" ? I can add "QProcess process;" prior to MainWindow::MainWindow..., and it works, but I don't think that is what you're suggesting is a global. Very noob, sorry. – Alan Nov 24 '16 at 00:05
  • @Alan To get more information about field members and other C++ `class` features read ["Class declaration"](http://en.cppreference.com/w/cpp/language/class) specification. The most interesting part for you is *Member specification*. – Nikita Nov 24 '16 at 06:18
0

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;
}
HazemGomaa
  • 1,620
  • 2
  • 14
  • 21
  • process->readAllStandardOutput(); fails on compile, adberror() doesn't know what it is. – Alan Nov 24 '16 at 00:33
  • @Alan that's why in my answer I mentioned that you need to make **process a member variable** of MainWindow – HazemGomaa Nov 24 '16 at 00:39
  • Thanks HG. I'd appreciate it if you could explain how that's done. As I mentioned above I can add "QProcess process;" in my mainwindow.cpp prior to MainWindow::MainWindow." and it works, but I don't think that's what you mean. – Alan Nov 24 '16 at 02:14
  • @Alan I added more details for the 2nd solution. you should consider the 1st solution first since it's easier. – HazemGomaa Nov 24 '16 at 03:24