Results 1 to 12 of 12

Thread: Communication between QThread and Yes/No QMessageBox?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2007
    Location
    Hamburg, Germany
    Posts
    11
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    1

    Default Re: Communication between QThread and Yes/No QMessageBox?

    Nothing, it's not implemented yet! It's a consideration so far!

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

    Default Re: Communication between QThread and Yes/No QMessageBox?

    I have an application that uses tape drives. The thread needs to ask if there are any more tapes for the job, SCSI errors, file dialogs...

    This method uses QT3, I have not ported this application to QT4 yet.

    Qt Code:
    1. in your application
    2.  
    3. void TapeMan::customEvent( QCustomEvent *event )
    4. {
    5. if( event->type() == QEvent::User + 3 ) // display message box
    6. {
    7. MessageBoxEvent *me = ( MessageBoxEvent* )event;
    8. ThreadMessageBox *tm = me->tm;
    9.  
    10. if( me->kind == TMSG_WARN )
    11. tm->messageResult = QMessageBox::warning( this, me->caption, me->message,
    12. me->button0, me->button1, me->button2 );
    13. if( me->kind == TMSG_INFO )
    14. tm->messageResult = QMessageBox::information( this, me->caption,
    15. me->message, me->button0, me->button1, me->button2 );
    16. if( me->kind == TMSG_STOP )
    17. tm->messageResult = QMessageBox::critical( this, me->caption, me->message,
    18. me->button0, me->button1, me->button2 );
    19. }
    20. }
    21.  
    22. and then 2 classes
    23.  
    24. #ifndef THREADMESSAGEBOX_H
    25. #define THREADMESSAGEBOX_H
    26.  
    27. #include <qstring.h>
    28. #include <qmessagebox.h>
    29.  
    30. class ThreadMessageBox
    31. {
    32. public:
    33. ThreadMessageBox( THREAD_MESSAGE kind, const QString &caption, const
    34. QString& message, int button0, int button1=QMessageBox::NoButton,
    35. int button2=QMessageBox::NoButton );
    36.  
    37. ~ThreadMessageBox();
    38.  
    39. int messageResult;
    40. };
    41.  
    42. #endif
    43.  
    44. #include "threadmessagebox.h"
    45. #include "messageboxevent.h"
    46.  
    47. #include <qapplication.h>
    48.  
    49. extern TapeMan *gApp;
    50.  
    51. ThreadMessageBox::ThreadMessageBox( THREAD_MESSAGE kind, const QString &caption,
    52. const QString& message, int button0, int button1, int button2 )
    53. {
    54. MessageBoxEvent *mess = new MessageBoxEvent( this, kind, caption, message,
    55. button0, button1, button2 );
    56.  
    57. messageResult = -99999;
    58.  
    59. QApplication::postEvent( gApp, mess ); // post event
    60.  
    61. while( messageResult == -99999 ) // wait
    62. {
    63. sleep( 1 );
    64. }
    65. }
    66.  
    67. ThreadMessageBox::~ThreadMessageBox()
    68. {
    69. }
    70.  
    71. #ifndef MESSAGE_BOX_EVENT_H
    72. #define MESSAGE_BOX_EVENT_H
    73.  
    74. #include <qevent.h>
    75. #include <qmessagebox.h>
    76. #include <qdeepcopy.h>
    77.  
    78. class ThreadMessageBox;
    79.  
    80. class MessageBoxEvent : public QCustomEvent
    81. {
    82. public:
    83. MessageBoxEvent( ThreadMessageBox *tm, THREAD_MESSAGE kind, const QString &caption,
    84. const QString& message, int button0, int button1=QMessageBox::NoButton,
    85. int button2=QMessageBox::NoButton );
    86. ~MessageBoxEvent();
    87.  
    88. THREAD_MESSAGE kind; // kind of message box
    89.  
    90. QDeepCopy<QString> caption; // caption for message box
    91. QDeepCopy<QString> message; // text for message
    92.  
    93. int button0; // buttons to display
    94. int button1;
    95. int button2;
    96.  
    97. ThreadMessageBox *tm; // pointer to thread message box
    98. };
    99. #endif
    100.  
    101. #include "messageboxevent.h"
    102.  
    103. MessageBoxEvent::MessageBoxEvent( ThreadMessageBox *tm, THREAD_MESSAGE kind,
    104. const QString &caption, const QString& message,
    105. int button0, int button1, int button2 ) : QCustomEvent( QEvent::User+3 )
    106. {
    107. this->kind = kind;
    108. this->caption = caption;
    109. this->message = message;
    110. this->button0 = button0;
    111. this->button1 = button1;
    112. this->button2 = button2;
    113. this->tm = tm;
    114. }
    115.  
    116. MessageBoxEvent::~MessageBoxEvent()
    117. {
    118. }
    119.  
    120. to get a message box from your thread
    121.  
    122. ThreadMessageBox mess = ThreadMessageBox( TMSG_INFO, "Tape Done", "Are there any more tapes",
    123. QMessageBox::Yes, QMessageBox::No ); // will block until message box is closed
    124.  
    125. if( mess.messageResult == QMessageBox::Yes )
    126. // do action here!
    To copy to clipboard, switch view to plain text mode 

    You need to use QDeepCopy's to insure each thread has a unique copy of the strings. This is not needed in QT4. The wait loop is a simple sleep. That is all that was needed for this application.
    Last edited by jacek; 25th January 2007 at 01:54. Reason: wrapped too long lines

  3. #3
    Join Date
    Oct 2006
    Posts
    279
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    6
    Thanked 40 Times in 39 Posts

    Default Re: Communication between QThread and Yes/No QMessageBox?

    As long as the tQThread object was created in the Gui thread, you can set up a connection between a private signal and a private slot. For the synchronization you need a QWaitCondition and a QMutex.
    e.g.:
    Qt Code:
    1. class WorkingThread : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. WorkingThread(QObject*parent=0);
    6. protected:
    7. virtual void run();
    8. signals:
    9. void askAQuestion( const QString& question, QMessageBox::StandardButton* answer);
    10. private slots:
    11. void questionAsked(const QString& question, QMessageBox::StandardButton* answer);
    12. private:
    13. QWaitCondition waitCondition;
    14. QMutex mutex;
    15. };
    16.  
    17. WorkingThread::WorkingThread(QObject*parent)
    18. : QThread(parent=0)
    19. {
    20. connect(this, SIGNAL(askAQuestion( const QString&, QMessageBox::StandardButton*)),
    21. this, SLOT(questionAsked( const QString&, QMessageBox::StandardButton*)));
    22. }
    23.  
    24. void WorkingThread::run()
    25. {
    26. QMessageBox::StandardButton answer = QMessageBox::Yes;
    27. do
    28. {
    29. QMutexLocker locker(&mutex);
    30. emit askAQuestion( "do you want to continue?", &answer);
    31. waitCondition.wait(&mutex);
    32. }
    33. while(answer == QMessageBox::Yes);
    34. }
    35.  
    36. void WorkingThread::questionAsked(const QString& question, QMessageBox::StandardButton* answer)
    37. {
    38. QMutexLocker locker(&mutex);
    39. *answer = QMessageBox::question(0, "Question:", question, QMessageBox::Yes|QMessageBox::No);
    40. waitCondition.wakeOne();
    41. }
    To copy to clipboard, switch view to plain text mode 

    The connection will automatically be queued since the run() function doesn't reside in the same thread as the QThread object, thus it's safe to use a messagebox.

    Good luck!
    Attached Files Attached Files

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.