Results 1 to 10 of 10

Thread: a QProcess + QThread question

  1. #1
    Join Date
    Oct 2010
    Location
    Tijuana, Baja California, México
    Posts
    19
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Talking a QProcess + QThread question

    I'm re-taking an old project about a bunch of files convert it, with ffmpeg, to mp3. At this point everything is good, only one thing left...unfreeze the GUI, this is my ffmpeg class:
    Qt Code:
    1. #ifndef FFMPEG_RUNNER_HPP
    2. #define FFMPEG_RUNNER_HPP
    3.  
    4. #include <QDebug>
    5. #include <QDir>
    6. #include <QFileInfo>
    7. #include <QProcess>
    8.  
    9. class MyFfmpegRunnerClass : public QObject {
    10. Q_OBJECT
    11. private:
    12. QProcess *process;
    13. QString curr_file;
    14. QString _in_file;
    15. QString _outdir;
    16. bool delete_me;
    17. public:
    18. MyFfmpegRunnerClass(QObject *parent = 0) : QObject(parent)
    19. {
    20. process = new QProcess(this);
    21. process->setStandardOutputFile("/dev/null");
    22. process->setStandardErrorFile("/dev/null");
    23. connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleprocessExited(int, QProcess::ExitStatus)));
    24. }
    25. void SetArguments(const QString& in_file, const QString& outdir, bool be_deleted = false) {
    26. _in_file = in_file;
    27. _outdir = outdir;
    28. delete_me = be_deleted;
    29. }
    30.  
    31. ~MyFfmpegRunnerClass() {
    32. delete process;
    33. qDebug() << "Class ffmpeg died";
    34. }
    35.  
    36. protected slots:
    37. void handleprocessExited(int exitCode, QProcess::ExitStatus exitStatus) {
    38. qDebug() << "Exited code: " << exitCode << ". ExitStatus: " << exitStatus;
    39. if ( (exitCode == 0) && (delete_me) ) {
    40. // you should delete source file here
    41. }
    42. emit doneJob();
    43. }
    44.  
    45. void Start() {
    46. QFileInfo fi(_in_file);
    47. QString file = fi.baseName() + ".mp3";
    48. QString out_file = QDir(_outdir).filePath(file);
    49. qDebug() << "Converting: " << out_file;
    50. curr_file = _in_file;
    51.  
    52. process->start("ffmpeg", QStringList() << "-i" << _in_file << "-f" << "mp3" << "-ab" << "128k" << out_file);
    53. process->waitForFinished(-1);
    54. process->close();
    55. }
    56.  
    57. signals:
    58. void doneJob();
    59. };
    60.  
    61.  
    62. #endif
    To copy to clipboard, switch view to plain text mode 
    And this is my GUI app:
    Qt Code:
    1. #ifndef TEST01_HPP
    2. #define TEST01_HPP
    3.  
    4. #include <QApplication>
    5. #include <QWidget>
    6. #include <QFileDialog>
    7. #include <QDir>
    8. #include <QDesktopServices> // Qt 4.2
    9. #include <QThread>
    10. #include <QMutex>
    11. #include "ui_test01.h"
    12. #include "ffmpeg_runner.hpp"
    13.  
    14. namespace Ui {
    15. class Form;
    16. };
    17.  
    18. class MyForm : public QWidget {
    19. Q_OBJECT
    20. private:
    21. Ui::Form *ui;
    22. QThread *thread;
    23. MyFfmpegRunnerClass *ffmpeg;
    24. QMutex mMutex; // do I need this? :-/
    25. public:
    26. MyForm(QWidget *root = 0) : QWidget(root), ui(new Ui::Form)
    27. {
    28. ui->setupUi(this);
    29.  
    30. /* above is beta, watch it!!! */
    31. thread = new QThread;
    32. ffmpeg = new MyFfmpegRunnerClass;
    33. ffmpeg->moveToThread(thread);
    34. connect(thread, SIGNAL(started()), ffmpeg, SLOT(Start()));
    35. connect(ffmpeg, SIGNAL(doneJob()), thread, SLOT(quit()));
    36. /* ... */
    37.  
    38. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(handleRunButton()));
    39. connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(handleBrowseButton()));
    40. ui->lineEdit->setText(QDesktopServices::storageLocation(QDesktopServices::MoviesLocation));
    41. }
    42. virtual ~MyForm() {
    43. delete ffmpeg;
    44. delete thread;
    45. delete ui;
    46. }
    47.  
    48. protected:
    49. void handleTraverseDirectory(const QString& source_dir, const QString& target_dir, bool delete_me) {
    50. if (!source_dir.isEmpty()) {
    51. QDir folder(source_dir);
    52. folder.setNameFilters(QStringList() << "*.mp3" << "*.mp4" << "*.flv" << "*.wav" << "*.ogg" << "*.3gp");
    53. QStringList files = folder.entryList(QDir::NoDotAndDotDot|QDir::Files);
    54. int index;
    55. /* run above and wait until there's no more files to convert */
    56. for (index = 0; index != files.size(); index++) {
    57. QFileInfo fi(source_dir, files.at(index));
    58. ffmpeg->SetArguments(fi.absoluteFilePath(), target_dir, delete_me);
    59. thread->start(); // this is fine :)
    60. thread->wait(); // keeps freeze :(
    61. }
    62. /* we should see the above message until last file is converted */
    63. qDebug() << "Done.";
    64. }
    65. }
    66.  
    67. protected slots:
    68. void handleBrowseButton() {
    69. QString folder = QFileDialog::getExistingDirectory(this);
    70. if (!folder.isEmpty()) ui->lineEdit->setText(folder);
    71. }
    72.  
    73. void handleRunButton() {
    74. QString source_dir = ui->lineEdit->text();
    75. QString target_dir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
    76. bool delete_me = true;
    77. /* need here to be async? */
    78. handleTraverseDirectory(source_dir, target_dir, delete_me);
    79. }
    80.  
    81. };
    82.  
    83. #endif
    To copy to clipboard, switch view to plain text mode 
    I'm using threads to keep unfreeze my GUI, but:

    1.- I need "waitForFinished" to let ffmpeg terminates the convertion (no big deal here)
    2.- I'm trying to emulate what glib's g_thread_create and what QtConcurrent::run do, but with threads to learn more about them with qprocess...

    what would be left to do so the GUI keeps "alive"? Thanks

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: a QProcess + QThread question

    Do not call waitForFinished() if you want the GUI to remain responsive. Disable elements of the UI that should not be usable during the life of the subprocess, start the sub process, use the finished() signal from the QProcess instance to determine when the process is done, and reenable parts pf the UI. You do not need threads at all to achieve this.

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

    Default Re: a QProcess + QThread question

    Well, you tell the main thread to wait for the other thread, so it blocks until the other thread ends.
    Which happens when your runner class emits doneJob() as this quits the thread's event loop.

    So effectively you always have only one running thread, i.e. you have the very same behavior as when you would not have the second thread, just that the code is more complicated

    This is also a classic example of not needing any additional threads at all, since QProcess is asynchronous itself.

    Cheers,
    _

  4. #4
    Join Date
    Oct 2010
    Location
    Tijuana, Baja California, México
    Posts
    19
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Red face Re: a QProcess + QThread question

    ok, I manage to remove threads and yes, QProcess is async, but..seems that tries to convert all at the same time, that's why I was using waitforfinish...my updated codes:
    Qt Code:
    1. #ifndef TEST01_HPP
    2. #define TEST01_HPP
    3.  
    4. #include <QApplication>
    5. #include <QWidget>
    6. #include <QFileDialog>
    7. #include <QDir>
    8. #include <QDesktopServices> // Qt 4.2
    9. #include "ui_test01.h"
    10. #include "ffmpeg_runner.hpp"
    11.  
    12. namespace Ui {
    13. class Form;
    14. };
    15.  
    16. class MyForm : public QWidget {
    17. Q_OBJECT
    18. private:
    19. Ui::Form *ui;
    20. MyFfmpegRunnerClass *ffmpeg;
    21. public:
    22. MyForm(QWidget *root = 0) : QWidget(root), ui(new Ui::Form)
    23. {
    24. ui->setupUi(this);
    25.  
    26. /* below is beta, watch it!!! */
    27. ffmpeg = new MyFfmpegRunnerClass(this);
    28. connect(ffmpeg, SIGNAL(startJob()), this, SLOT(handleStart()));
    29. connect(ffmpeg, SIGNAL(endJob()), this, SLOT(handleEnd()));
    30. /* ... */
    31.  
    32. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(handleRunButton()));
    33. connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(handleBrowseButton()));
    34. ui->lineEdit->setText(QDesktopServices::storageLocation(QDesktopServices::MoviesLocation));
    35. }
    36. virtual ~MyForm() {
    37. delete ffmpeg;
    38. delete ui;
    39. }
    40.  
    41. protected:
    42.  
    43. signals:
    44. void doneJob();
    45.  
    46. protected slots:
    47. void handleBrowseButton() {
    48. QString folder = QFileDialog::getExistingDirectory(this);
    49. if (!folder.isEmpty()) ui->lineEdit->setText(folder);
    50. }
    51.  
    52. void handleRunButton() {
    53. QString source_dir = ui->lineEdit->text();
    54. QString target_dir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
    55. bool delete_me = true;
    56. ffmpeg->Start(source_dir, target_dir, delete_me);
    57. }
    58.  
    59. void handleStart() {
    60. qDebug() << "We start the process";
    61. }
    62.  
    63. void handleEnd() {
    64. qDebug() << "Done :v";
    65. }
    66.  
    67. };
    68.  
    69. #endif
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #ifndef FFMPEG_RUNNER_HPP
    2. #define FFMPEG_RUNNER_HPP
    3.  
    4. #include <QDebug>
    5. #include <QDir>
    6. #include <QFileInfo>
    7. #include <QProcess>
    8.  
    9. class MyFfmpegRunnerClass : public QObject {
    10. Q_OBJECT
    11. private:
    12. QProcess *process;
    13. QString curr_file;
    14. bool delete_me;
    15. int n_files;
    16. public:
    17. MyFfmpegRunnerClass(QObject *parent = 0) : QObject(parent)
    18. {
    19. n_files = 0;
    20. process = new QProcess(this);
    21. process->setStandardOutputFile("/dev/null");
    22. process->setStandardErrorFile("/dev/null");
    23. connect(process, SIGNAL(started()), this, SLOT(handleprocessStarted()));
    24. connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleprocessExited(int, QProcess::ExitStatus)));
    25. }
    26.  
    27. void Start(const QString& srcdir, const QString& outdir, bool be_deleted = false) {
    28. QDir folder(srcdir);
    29. folder.setNameFilters(QStringList() << "*.mp3" << "*.mp4" << "*.flv" << "*.wav" << "*.ogg" << "*.3gp");
    30. QStringList files = folder.entryList(QDir::NoDotAndDotDot|QDir::Files);
    31. delete_me = be_deleted;
    32. n_files = files.size();
    33. int index;
    34. for (index = 0; index != n_files; index++) {
    35. QFileInfo fi(srcdir, files.at(index));
    36. QString file = fi.baseName() + ".mp3";
    37. curr_file = fi.absoluteFilePath();
    38. QString out_file = QDir(outdir).filePath(file);
    39. qDebug() << "Converting: " << curr_file;
    40. process->start("ffmpeg", QStringList() << "-i" << curr_file << "-f" << "mp3" << "-ab" << "128k" << out_file);
    41. }
    42. // here we should wait until all files are converted, right?
    43. qDebug() << "Why do you see this line even the process is still converting?"
    44. }
    45.  
    46. ~MyFfmpegRunnerClass() {
    47. if (process->pid()) process->close();
    48. delete process;
    49. qDebug() << "Class ffmpeg died";
    50. }
    51.  
    52. protected slots:
    53. void handleprocessStarted() {
    54. emit startJob();
    55. }
    56.  
    57. void handleprocessExited(int exitCode, QProcess::ExitStatus exitStatus) {
    58. qDebug() << "Exited code: " << exitCode << ". ExitStatus: " << exitStatus;
    59. if ( (exitCode == 0) && (delete_me) ) {
    60. process->close();
    61. emit endJob();
    62. // you should delete source file here
    63. }
    64. }
    65.  
    66. signals:
    67. void startJob();
    68. void endJob();
    69. };
    70.  
    71.  
    72. #endif
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: a QProcess + QThread question

    If you do not want to start a process for everything at the same time then don't code it to do that. Implement some sort of job queue from which you start the first n entries (where n == 1 is effectively serial processing). When a sub-process finishes look at the queue and start the next item if there is one.

  6. #6
    Join Date
    Oct 2010
    Location
    Tijuana, Baja California, México
    Posts
    19
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: a QProcess + QThread question

    oh I see what you guys are telling me, things finally coming together, only one thing left, I'm getting a core dump segment fault, when I close my GUI, see my updated code:
    Qt Code:
    1. #ifndef FFMPEG_RUNNER_HPP
    2. #define FFMPEG_RUNNER_HPP
    3.  
    4. #include <QDebug>
    5. #include <QDir>
    6. #include <QFileInfo>
    7. #include <QProcess>
    8.  
    9. class MyFfmpegRunnerClass : public QObject {
    10. Q_OBJECT
    11. private:
    12. QProcess *process;
    13. QString srcdir;
    14. QString outdir;
    15. QString curr_file;
    16. bool delete_me;
    17. int n_files;
    18. QStringList files;
    19. int index;
    20. public:
    21. MyFfmpegRunnerClass(QObject *parent = 0) : QObject(parent)
    22. {
    23. /* init some values */
    24. n_files = 0;
    25. index = 0;
    26. }
    27.  
    28. void Start(const QString& _srcdir, const QString& _outdir, bool be_deleted = false) {
    29. /* grab values from parent's */
    30. srcdir = _srcdir;
    31. outdir = _outdir;
    32. delete_me = be_deleted;
    33. /* grab only selected files */
    34. QDir folder(srcdir);
    35. folder.setNameFilters(QStringList() << "*.mp3" << "*.mp4" << "*.flv" << "*.wav" << "*.ogg" << "*.3gp");
    36. files = folder.entryList(QDir::NoDotAndDotDot|QDir::Files);
    37. n_files = files.size(); // hold the number of them
    38. emit aJob();
    39. handleNewJob(); // begin job
    40. }
    41.  
    42. ~MyFfmpegRunnerClass() {
    43. /* ok, test if a process is running before a suicide */
    44. if (process && process->pid()) {
    45. process->close();
    46. delete process; // problem here?? :-/
    47. }
    48. qDebug() << "Class ffmpeg died -_-";
    49. }
    50.  
    51. protected:
    52. void handleNewJob() {
    53. /* do we have more files for the job? */
    54. if (index < n_files) {
    55. process = new QProcess(this);
    56. process->setStandardOutputFile("/dev/null");
    57. process->setStandardErrorFile("/dev/null");
    58. connect(process, SIGNAL(started()), this, SLOT(handleprocessStarted()));
    59. connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleprocessExited(int, QProcess::ExitStatus)));
    60. QFileInfo fi(srcdir, files.at(index));
    61. QString file = fi.baseName() + ".mp3";
    62. curr_file = fi.absoluteFilePath();
    63. QString out_file = QDir(outdir).filePath(file);
    64. process->start("ffmpeg", QStringList() << "-i" << curr_file << "-f" << "mp3" << "-ab" << "128k" << out_file);
    65. qDebug() << "Converting: " << curr_file;
    66. index++;
    67. } else {
    68. emit noMoreJob();
    69. }
    70. }
    71.  
    72. protected slots:
    73. void handleprocessStarted() {
    74. emit startJob();
    75. }
    76.  
    77. void handleprocessExited(int exitCode, QProcess::ExitStatus exitStatus) {
    78. qDebug() << "Exited code: " << exitCode << ". ExitStatus: " << exitStatus;
    79. if ( (exitCode == 0) && (delete_me) ) {
    80. process->close();
    81. emit endJob();
    82. delete process; // delete old, before new?
    83. handleNewJob(); // look for more files
    84. // you should delete source file here
    85. }
    86. }
    87.  
    88. signals:
    89. void aJob();
    90. void startJob();
    91. void noMoreJob();
    92. void endJob();
    93. };
    94.  
    95.  
    96. #endif
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #ifndef TEST01_HPP
    2. #define TEST01_HPP
    3.  
    4. #include <QApplication>
    5. #include <QWidget>
    6. #include <QFileDialog>
    7. #include <QDir>
    8. #include <QDesktopServices> // Qt 4.2
    9. #include "ui_test01.h"
    10. #include "ffmpeg_runner.hpp"
    11.  
    12. namespace Ui {
    13. class Form;
    14. };
    15.  
    16. class MyForm : public QWidget {
    17. Q_OBJECT
    18. private:
    19. Ui::Form *ui;
    20. MyFfmpegRunnerClass *ffmpeg;
    21. public:
    22. MyForm(QWidget *root = 0) : QWidget(root), ui(new Ui::Form)
    23. {
    24. ui->setupUi(this);
    25.  
    26. /* below is beta, watch it!!! */
    27. ffmpeg = new MyFfmpegRunnerClass(this);
    28. connect(ffmpeg, SIGNAL(aJob()), this, SLOT(handleAJob()));
    29. connect(ffmpeg, SIGNAL(startJob()), this, SLOT(handleStart()));
    30. connect(ffmpeg, SIGNAL(endJob()), this, SLOT(handleEnd()));
    31. connect(ffmpeg, SIGNAL(noMoreJob()), this, SLOT(handleNoMoreJob()));
    32. /* ... */
    33.  
    34. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(handleRunButton()));
    35. connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(handleBrowseButton()));
    36. ui->lineEdit->setText(QDesktopServices::storageLocation(QDesktopServices::MoviesLocation));
    37. }
    38. virtual ~MyForm() {
    39. delete ffmpeg;
    40. delete ui;
    41. }
    42.  
    43. protected slots:
    44. void handleBrowseButton() {
    45. QString folder = QFileDialog::getExistingDirectory(this);
    46. if (!folder.isEmpty()) ui->lineEdit->setText(folder);
    47. }
    48.  
    49. void handleRunButton() {
    50. QString source_dir = ui->lineEdit->text();
    51. QString target_dir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
    52. bool delete_me = true;
    53. ffmpeg->Start(source_dir, target_dir, delete_me);
    54. qDebug() << "Say hello";
    55. }
    56.  
    57. void handleStart() {
    58. qDebug() << "We have a new job";
    59. }
    60.  
    61. void handleEnd() {
    62. qDebug() << "We don't have the job";
    63. }
    64.  
    65. void handleAJob() {
    66. qDebug() << "We should disable some stuff here";
    67. }
    68.  
    69. void handleNoMoreJob() {
    70. qDebug() << "We should enable some stuff here";
    71. }
    72.  
    73. };
    74.  
    75. #endif
    To copy to clipboard, switch view to plain text mode 
    The message "Class ffmpeg died -_-" doesn't showed when I close my app, what could it be?

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: a QProcess + QThread question

    You don't need a new QProcess per job, one should do.

    If you want to use a new QProcess instance, do not delete the old one directly but use deleteLater(). You are at that point in a slot connected to the process, directly deleting it is not very good.

    Also kill the process in the runner's destructor.

    Cheers,
    _

  8. #8
    Join Date
    Oct 2010
    Location
    Tijuana, Baja California, México
    Posts
    19
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: a QProcess + QThread question

    Wow, I think I got it, no errors, no segment fault:
    Qt Code:
    1. #ifndef FFMPEG_RUNNER_HPP
    2. #define FFMPEG_RUNNER_HPP
    3.  
    4. #include <QDebug>
    5. #include <QDir>
    6. #include <QFileInfo>
    7. #include <QProcess>
    8.  
    9. class MyFfmpegRunnerClass : public QObject {
    10. Q_OBJECT
    11. private:
    12. QProcess *process;
    13. QString srcdir;
    14. QString outdir;
    15. QString curr_file;
    16. bool delete_me;
    17. int n_files;
    18. QStringList files;
    19. int index;
    20. public:
    21. MyFfmpegRunnerClass(QObject *parent = 0) : QObject(parent)
    22. {
    23. /* init some values */
    24. n_files = 0;
    25. index = 0;
    26.  
    27. /* we should use one QProcess instance, thread safe? */
    28. process = new QProcess(this);
    29. process->setStandardOutputFile("/dev/null");
    30. process->setStandardErrorFile("/dev/null");
    31. connect(process, SIGNAL(started()), this, SLOT(handleprocessStarted()));
    32. connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleprocessExited(int, QProcess::ExitStatus)));
    33. //connect(process, SIGNAL(finished(int)), process, SLOT(deleteLater())); <-- We don't need this, do we?
    34. }
    35.  
    36. void Start(const QString& _srcdir, const QString& _outdir, bool be_deleted = false) {
    37. /* grab values from parent's */
    38. srcdir = _srcdir;
    39. outdir = _outdir;
    40. delete_me = be_deleted;
    41. /* grab only selected files */
    42. QDir folder(srcdir);
    43. folder.setNameFilters(QStringList() << "*.mp3" << "*.mp4" << "*.flv" << "*.wav" << "*.ogg" << "*.3gp");
    44. files = folder.entryList(QDir::NoDotAndDotDot|QDir::Files);
    45. n_files = files.size(); // hold the number of them
    46. emit aJob();
    47. handleNewJob(); // begin a job
    48. }
    49.  
    50. ~MyFfmpegRunnerClass() {
    51. /* ok, they kill us from parent's, so test if a process is running before a suicide */
    52. if (process && process->pid()) { //
    53. process->close();
    54. delete process; // This is not a problem anymore :)
    55. }
    56. qDebug() << "Class ffmpeg died -_-";
    57. }
    58.  
    59. protected:
    60. void handleNewJob() {
    61. /* do we have some files for the job? */
    62. if (index < n_files) {
    63. QFileInfo fi(srcdir, files.at(index));
    64. QString file = fi.baseName() + ".mp3";
    65. curr_file = fi.absoluteFilePath();
    66. QString out_file = QDir(outdir).filePath(file);
    67. process->start("ffmpeg", QStringList() << "-i" << curr_file << "-f" << "mp3" << "-ab" << "128k" << out_file);
    68. qDebug() << "Converting: " << curr_file;
    69. index++;
    70. } else {
    71. emit noMoreJob();
    72. }
    73. }
    74.  
    75. protected slots:
    76. void handleprocessStarted() {
    77. emit startJob();
    78. }
    79.  
    80. void handleprocessExited(int exitCode, QProcess::ExitStatus exitStatus) {
    81. qDebug() << "Exited code: " << exitCode << ". ExitStatus: " << exitStatus;
    82. if ( (exitCode == 0) && (delete_me) ) {
    83. emit endJob();
    84. handleNewJob(); // look for more files
    85. // you should delete source file here below
    86. }
    87. }
    88.  
    89. signals:
    90. void aJob();
    91. void startJob();
    92. void noMoreJob();
    93. void endJob();
    94. };
    95.  
    96.  
    97. #endif
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #ifndef TEST01_HPP
    2. #define TEST01_HPP
    3.  
    4. #include <QApplication>
    5. #include <QWidget>
    6. #include <QFileDialog>
    7. #include <QDir>
    8. #include <QDesktopServices> // Qt 4.2
    9. #include "ui_test01.h"
    10. #include "ffmpeg_runner.hpp"
    11.  
    12. namespace Ui {
    13. class Form;
    14. };
    15.  
    16. class MyForm : public QWidget {
    17. Q_OBJECT
    18. private:
    19. Ui::Form *ui;
    20. MyFfmpegRunnerClass *ffmpeg;
    21. public:
    22. MyForm(QWidget *root = 0) : QWidget(root), ui(new Ui::Form)
    23. {
    24. ui->setupUi(this);
    25.  
    26. /* below is beta, watch it!!! */
    27. ffmpeg = new MyFfmpegRunnerClass(this);
    28. connect(ffmpeg, SIGNAL(aJob()), this, SLOT(handleAJob()));
    29. connect(ffmpeg, SIGNAL(startJob()), this, SLOT(handleStart()));
    30. connect(ffmpeg, SIGNAL(endJob()), this, SLOT(handleEnd()));
    31. connect(ffmpeg, SIGNAL(noMoreJob()), this, SLOT(handleNoMoreJob()));
    32. /* ... */
    33.  
    34. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(handleRunButton()));
    35. connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(handleBrowseButton()));
    36. ui->lineEdit->setText(QDesktopServices::storageLocation(QDesktopServices::MoviesLocation));
    37. }
    38. virtual ~MyForm() {
    39. delete ffmpeg;
    40. delete ui;
    41. }
    42.  
    43. protected slots:
    44. void handleBrowseButton() {
    45. QString folder = QFileDialog::getExistingDirectory(this);
    46. if (!folder.isEmpty()) ui->lineEdit->setText(folder);
    47. }
    48.  
    49. void handleRunButton() {
    50. QString source_dir = ui->lineEdit->text();
    51. QString target_dir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
    52. bool delete_me = true;
    53. ffmpeg->Start(source_dir, target_dir, delete_me);
    54. }
    55.  
    56. void handleStart() {
    57. qDebug() << "We have a new job";
    58. }
    59.  
    60. void handleEnd() {
    61. qDebug() << "We don't have the job";
    62. }
    63.  
    64. void handleAJob() {
    65. qDebug() << "We should disable some stuff here";
    66. }
    67.  
    68. void handleNoMoreJob() {
    69. qDebug() << "We should enable some stuff here";
    70. }
    71.  
    72. };
    73.  
    74. #endif
    To copy to clipboard, switch view to plain text mode 
    in your opinion, everything is ok? No memory leaks?

  9. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: a QProcess + QThread question

    Looks good to me.

    One possible thing that your job queue based processing allows you to do is to emit progress information, e.g. something like "Processing file 2 of 23".

    Cheers,
    _

  10. The following user says thank you to anda_skoa for this useful post:

    Joelito (2nd March 2014)

  11. #10
    Join Date
    Oct 2010
    Location
    Tijuana, Baja California, México
    Posts
    19
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: a QProcess + QThread question

    ok, thanks for your help

Similar Threads

  1. Starting QProcess from QThread
    By sandeep.theartist in forum Qt Programming
    Replies: 2
    Last Post: 7th June 2012, 06:18
  2. QThread to run one or more QProcess
    By smhall316 in forum Newbie
    Replies: 0
    Last Post: 27th September 2011, 20:39
  3. [Article] How to QProcess in QThread
    By Raccoon29 in forum Qt Programming
    Replies: 6
    Last Post: 30th November 2009, 08:22
  4. QThread and QProcess problem
    By codebehind in forum Qt Programming
    Replies: 13
    Last Post: 7th August 2007, 08:11
  5. QProcess in a QThread
    By chombium in forum Qt Programming
    Replies: 2
    Last Post: 11th January 2006, 15:52

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
  •  
Qt is a trademark of The Qt Company.