You are not logged in.

RR_TW

Beginner

  • "RR_TW" is male
  • "RR_TW" started this thread

Posts: 39

Location: Taipei, Taiwan, R.O.C.

Occupation: IT

  • Send private message

1

Friday, April 23rd 2010, 11:00am

[Solved]Problem on QProcess's finished() SIGNAL

I had a class that inherit from QThread, and using QProcess to execute an external application.
Code was like this

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// header file
class PlayerT : public QThread
{
Q_OBJECT
public:
  void setup(some param);
  void run();
  QProcess *qp;
  QString cmd;
public slots:
  void stopped();
}

// cpp file
void PlayerT::setup(some param)
{
  // some code
}

void PlayerT::run()
{
  qDebug("THREAD: Waiting for 15 seconds to execute external APP...\n");
  SleeperThread::Sleep(15000);
  qp->execute(QString as command line);
//  connect(qp, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(stopped()));  //Add this line will cause error at runtime
}

void PlayerT::stopped()
{
  qDebug("THREAD: External APP ended...\n");
}


First of all, the external application was ok.
If I add the "connect..." code back, when the external application ended,
my code will shows a Segmentation fault error message, and whole Qt app was crashed...
Am I do anything wrong on this ?

This post has been edited 1 times, last edit by "RR_TW" (Apr 26th 2010, 12:33pm)


2

Friday, April 23rd 2010, 2:36pm

In this case slots are executed in GUI (a thread which creates the thread).

QProcess is executed asynchronously.

qp is _not_ created. No full example code (best is an example project) - no fun.

Source code

1
2
  qDebug("THREAD: Waiting for 15 seconds to execute external APP...\n");
  SleeperThread::Sleep(15000);

Any explanations?

PlayerT instance could be already destroyed when "stopped" slot is called.

Maybe make example project?
Fighting fire with fire.
Three can keep a secret if two of them are dead.

RR_TW

Beginner

  • "RR_TW" is male
  • "RR_TW" started this thread

Posts: 39

Location: Taipei, Taiwan, R.O.C.

Occupation: IT

  • Send private message

3

Monday, April 26th 2010, 6:53am

QThread & QProcess code

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// header file
class PlayerT : public QThread
{
Q_OBJECT
public:
  void setup(some param);
  void run();
  QProcess *qp;
  QString cmd;
public slots:
  void stopped();
}

// cpp file
void PlayerT::setup(QString param)
{
  cmd.append(param);
}

void PlayerT::run()
{
  qDebug("THREAD: Waiting for 15 seconds to execute external APP...\n");
  SleeperThread::Sleep(15000);
  qp->execute(cmd);
//  connect(qp, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(stopped()));  //Add this line will cause error at runtime
}

void PlayerT::stopped()
{
  qDebug("THREAD: External APP ended...\n");
}


The SleeperThread code

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef SLEEPERTHREAD_H
#define SLEEPERTHREAD_H
#include <QtCore/QThread>

class SleeperThread : public QThread
{
public:
  static void Sleep(unsigned long msecs)
  {
	QThread::msleep(msecs);
  }
};

#endif // SLEEPERTHREAD_H


The MainWindow code

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//header
namespace Ui
{
  class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT
public:
  PlayerT pT; //QThread to launch all players
};

//cpp
pT.setup("./xxxPlayer"); //An executable file on linux
pT.start();


Basic code here, I'll make an example project soon.
Thank you for took a look at my problem ^^

4

Monday, April 26th 2010, 7:07am

Please, explain where "QProcess *qp;" is pointing.
Public class variables - evilest evil :D
Fighting fire with fire.
Three can keep a secret if two of them are dead.

RR_TW

Beginner

  • "RR_TW" is male
  • "RR_TW" started this thread

Posts: 39

Location: Taipei, Taiwan, R.O.C.

Occupation: IT

  • Send private message

5

Monday, April 26th 2010, 7:36am

Hello, I just upload an example project, and what I'm running it in mt ubuntu 8.0.4 is
  1. Example project start, shows http://www.bing.com/ in a window
  2. Waiting for 15 seconds, will execute the "Text Editor" called gedit (in ubuntu, like notepad in Windows)
  3. And I just close the gedit, now example project just ended
  4. Whole message output...

Source code

1
2
3
4
Starting /tftpboot/test_code/TestProject/TestProject...
MSG: Start to run external application in 15 seconds...
The program has unexpectedly finished.
/tftpboot/test_code/TestProject/TestProject exited with code 0


BTW, I had add 1 line code after read your newest message

Source code

1
2
3
4
5
6
7
8
void PlayerT::run()
{
  qDebug("MSG: Start to run external application in 15 seconds...");
  SleeperThread::Sleep(15000);
  qp=new QProcess(); // This line just added
  qp->execute(cmd);
  connect(qp, SIGNAL(finished(int)), this, SLOT(stopped()));
}


But still can't get QProcess finished signal...
What should I do ?
RR_TW has attached the following file:
  • TestProject.zip (4.82 kB - 59 times downloaded - latest: Mar 5th 2013, 10:45am)

6

Monday, April 26th 2010, 10:47am

"execute" is static function. Use "start".
In my system it does not crashes but process is zombified. If I use

Source code

1
2
3
4
5
6
7
8
9
void PlayerT::run()
{
  qDebug("MSG: Start to run external application in 15 seconds...");
  //SleeperThread::Sleep(15000);
  qp = new QProcess;
  connect(qp, SIGNAL(finished(int)), this, SLOT(stopped()));
  qp->start(cmd);
  qp->waitForFinished();
} // the end of thread.

then it works ok.
I think the process becomes a zombie because the thread in which it started goes dead.
Fighting fire with fire.
Three can keep a secret if two of them are dead.

RR_TW

Beginner

  • "RR_TW" is male
  • "RR_TW" started this thread

Posts: 39

Location: Taipei, Taiwan, R.O.C.

Occupation: IT

  • Send private message

7

Monday, April 26th 2010, 12:03pm

Thank you Messenger, 你是最棒的(you are the best) :thumbup: :thumbup: :thumbup:

I can catch QProcess's finished() signal now,
and pass to other class as well~


Thank you again ^^