Results 1 to 3 of 3

Thread: QProcess in a QThread

  1. #1
    Join Date
    Jan 2006
    Location
    Skopje, Macedonia
    Posts
    11
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows Maemo/MeeGo

    Default QProcess in a QThread

    Hi,

    I needed repeatidly to start some external program from the app that I'm writing. The idea was to repeaiidly play wav files with aplay, at first I created QProcess in the gui thread and tested, but there were some delays in the playing due to other data processing in the app.

    I subclassed QThread and I've combined it with QProcess so that I can execute the external app.
    I'm using QT 3. I've read that the event loop runs in the gui thread and that threads are not well supported in Qt3.

    Here is the code:

    The header:
    Qt Code:
    1. // execthread.h
    2. // Description: Thread class for executing external applications repeatedly.
    3. // The external app can be executed repeatedly until the thread is stopped,
    4. // or a definite number of times. The executed command can be given, or it
    5. // can be read from some conf file which path will be given at thread creation.
    6.  
    7. #ifndef EXECTHREAD_H
    8. #define EXECTHREAD_H
    9.  
    10. #include <qthread.h>
    11. #include <qprocess.h>
    12. #include <qstringlist.h>
    13. #include <qstring.h>
    14. #include <qapplication.h>
    15.  
    16.  
    17. class ExecThread : public QThread
    18. {
    19. Q_OBJECT
    20. public:
    21. ExecThread(const QString Conf, int RunTimes, bool config);
    22. virtual ~ExecThread();
    23.  
    24. void setCommand(const QString Cmd);
    25. void setExecTimes(const int &ExecTimesParam);
    26. int execsTillStop();
    27. void run();
    28. void stop();
    29.  
    30.  
    31. signals:
    32. void ExecFinished(); // when in RepeatMode emits a signal after it finishes the last // execution
    33.  
    34.  
    35. private:
    36. QProcess *ExecProcess;
    37. QString CommandStr; // Command to be executed
    38. int ExecTimes; // number of executions to be done till it stops
    39. bool RepeatMode; // flag if the thread is in repeated execution
    40. volatile bool stopped; // flag if thread was stopped
    41.  
    42. QString GetCommandStr(const QString Path);
    43. void SetArgs(QString Cmd);
    44.  
    45. private slots:
    46. void processExitedSlot();
    47. };
    48.  
    49. #endif
    To copy to clipboard, switch view to plain text mode 

    And the implementation:
    Qt Code:
    1. // execthread.cpp
    2.  
    3.  
    4. #include "execthread.h"
    5.  
    6. // Function: ExecThread::ExecThread
    7. // Description: The constructor
    8. // Parameters:
    9. // QString Conf - the command to be executed, or the conf file to be read where the command is
    10. // int RunTimes - number of times the command should be executed. Default is 0, meaning
    11. // unlimited times ( till stop() method is called)
    12. // bool config - if true the first parameter (Conf) is the path to the config file where the
    13. // command is situated. By default it's false which means Conf holds the
    14. // command to be executed
    15.  
    16. ExecThread::ExecThread(const QString Conf, int RunTimes, bool config)
    17. {
    18.  
    19. stopped = true;
    20.  
    21. // setting the command to be executed
    22. if (!config)
    23. CommandStr = Conf;
    24. else
    25. CommandStr = GetCommandStr(Conf);
    26.  
    27.  
    28. // should the command be exectuted limited number of times
    29. if (RunTimes > 0)
    30. {
    31. ExecTimes = RunTimes;
    32. RepeatMode = true;
    33. }
    34. else
    35. {
    36. ExecTimes = 0;
    37. RepeatMode = false;
    38. }
    39.  
    40. CommandStr = CommandStr.stripWhiteSpace();
    41. CommandStr = CommandStr.simplifyWhiteSpace();
    42.  
    43. // create the process which will execute the command
    44. ExecProcess = new QProcess();
    45.  
    46. // QObject::connect( ExecProcess, SIGNAL(processExited()),
    47. // this, SLOT(processExitedSlot()) );
    48.  
    49. connect( ExecProcess, SIGNAL(processExited()),
    50. this, SLOT(processExitedSlot()) );
    51.  
    52.  
    53. SetArgs(CommandStr);
    54. }
    55.  
    56. // Function: ExecThread::~ExecThread
    57. // Description: The destructor
    58.  
    59. ExecThread::~ExecThread()
    60. {
    61. delete ExecProcess;
    62. }
    63.  
    64. // Funciton: GetCommandStr
    65. // Description: Parser for the file with the command string. It accepts # style comments
    66. // Parameters:
    67. // QString Path - the path to the file
    68.  
    69. QString ExecThread::GetCommandStr (const QString Path)
    70. {
    71. QFile file;
    72. QTextStream stream( &file );
    73. QString CmdStr = "";
    74. QString line;
    75. int pos;
    76.  
    77. file.setName(Path);
    78. if (!file.exists()) return "";
    79. if (file.open(IO_ReadOnly))
    80. while (( !stream.atEnd() ) or (CmdStr == ""))
    81. {
    82. line = stream.readLine();
    83.  
    84. if ((pos = line.find('#',0))>=0) // if there is a # in the line
    85. {
    86. if (pos > 0) // if the line is like " aplay /usr/test.wav # play test.wav"
    87. CmdStr = line.left(pos);
    88. }
    89. else
    90. {
    91. CmdStr = line;
    92. }
    93. }
    94. return CmdStr;
    95. }
    96.  
    97. // Funciton: setCommand
    98. // Description: Sets the command to be executed
    99. // Parameters:
    100. // QString Cmd - the command
    101.  
    102. void ExecThread::setCommand(const QString Cmd)
    103. {
    104.  
    105.  
    106. CommandStr = Cmd;
    107. CommandStr = CommandStr.stripWhiteSpace();
    108. CommandStr = CommandStr.simplifyWhiteSpace();
    109. SetArgs(CommandStr);
    110. return;
    111. }
    112.  
    113. // Funciton: setExecTimes
    114. // Description: Sets the number of times command should be exectuted.
    115. // Calling this function autmatically sets RepeatMode to true
    116. // Parameters:
    117. // int &ExecTimesParam - number of times command to be executed
    118.  
    119. void ExecThread::setExecTimes(const int &ExecTimesParam)
    120. {
    121. if (ExecTimesParam > 0)
    122. {
    123. ExecTimes = ExecTimesParam;
    124. RepeatMode = true;
    125. }
    126. else
    127. {
    128. ExecTimes = 0;
    129. RepeatMode = false;
    130. }
    131. }
    132.  
    133.  
    134. // Funciton: run
    135. // Description: Executes the command until stopped is true. In RepeatMode
    136. // decreases the number of execs to be done be executed
    137.  
    138. void ExecThread::run()
    139. {
    140. stopped = false;
    141. ExecProcess->start();
    142. if (RepeatMode)
    143. {
    144. ExecTimes--;
    145. if (ExecTimes == 0)
    146. {
    147. stopped = true;
    148. emit ExecFinished();
    149. }
    150. }
    151. }
    152.  
    153. // Function: stop
    154. // Description: Sets stopped to true. Stops the execution, but the command that is currently
    155. // running is not terminated
    156.  
    157. void ExecThread::stop()
    158. {
    159. stopped = true;
    160. }
    161.  
    162. // Function: SetArgs
    163. // Description: Sets the command arguments to ExecProcess
    164. // Parameters:
    165. // QString Cmd - the command
    166.  
    167. void ExecThread::SetArgs(QString Cmd)
    168. {
    169. int pos;
    170.  
    171. ExecProcess->clearArguments();
    172. while ((pos = Cmd.find(" ",0))> 0)
    173. {
    174. ExecProcess->addArgument(Cmd.left(pos));
    175. Cmd = Cmd.mid(pos + 1, 1000);
    176. }
    177. ExecProcess->addArgument(Cmd);
    178. }
    179.  
    180. // Function: execsTillStop
    181. // Description: Returns the number of exectutions till it stops ExecProcess
    182. int ExecThread::execsTillStop()
    183. {
    184. return ExecTimes;
    185. }
    186.  
    187.  
    188.  
    189. void ExecThread::processExitedSlot()
    190. {
    191. if (!stopped)
    192. {
    193. ExecProcess->start();
    194. if (RepeatMode)
    195. {
    196. ExecTimes--;
    197. if (ExecTimes == 0)
    198. {
    199. stopped = true;
    200. emit ExecFinished();
    201. }
    202. }
    203. }
    204. }
    To copy to clipboard, switch view to plain text mode 

    I've hit the wall twice

    1. the connect statment gives me an error when compiling

    execthread.cpp:56: error: no matching function for call to Object::connect(QProcess*&, const char [17], ExecThread* const, const char [21])
    /usr/include/qt3/qobject.h:116: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*)
    /usr/include/qt3/qobject.h:226: note: bool QObject::connect(const QObject*, const char*, const char*) const


    2. If I comment the connect statement, the code compiles well but I get error in linking stage. I don't understand why do I get this error, ExitFinished() is defined as signal. confused

    execthread.cppunhappy .text+0x7c): undefined reference to `ExecThread::ExecFinished()'execthread.o: In function `ExecThread:rocessExitedSlot()':
    execthread.cppunhappy .text+0xee): undefined reference to `ExecThread::ExecFinished()'collect2: ld returned 1 exit status


    TIA, chombium

  2. #2
    Join Date
    Jan 2006
    Posts
    32
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QProcess in a QThread

    afaik QThreads are not QObjects in Qt3, so you can't emit signals and activate slots. I think you have to derive from both QThread and QObject if you need this features, but be careful.

    in Qt4, instead, QThreads are Qobjects (so they have signals and slots) and they have their own event loop.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QProcess in a QThread

    QProcess is an event loop driven class, it can only be used in the main thread (event loop thread)

    You could use a Thread and system() to start the external player

    Cheers,
    _

Similar Threads

  1. CPU Time & Memory Usage in QThread or QProcess
    By Davidaino in forum Qt Programming
    Replies: 0
    Last Post: 11th July 2008, 20:15
  2. Detect First QProcess finished in a group and kill other
    By Davidaino in forum Qt Programming
    Replies: 3
    Last Post: 11th July 2008, 13:53
  3. QThread and QProcess problem
    By codebehind in forum Qt Programming
    Replies: 13
    Last Post: 7th August 2007, 09:11
  4. QProcess and Pipes
    By KaptainKarl in forum Qt Programming
    Replies: 1
    Last Post: 10th April 2007, 00:11
  5. Replies: 4
    Last Post: 27th July 2006, 12:13

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.