Results 1 to 12 of 12

Thread: Communication between QThread and Yes/No QMessageBox?

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

    Default Communication between QThread and Yes/No QMessageBox?

    Hi,

    is there a way to show a QMessageBox and get the return code (yes/no message box) out of a thread (QThread subclass)?

    Thanks!
    Chris

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

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

    Unfortunately no, because you may not touch the GUI from any other than the main GUI thread.
    J-P Nurmi

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

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

    ...mmmhhhh, no chance with connections or events?

    If the messagebox create process in main thread and call this with connection from second thread and return the result (yes/no) back via connection to second thread?

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

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

    Of course it's possible. The messagebox just has to be exec'd in the main thread. Use queued signals or custom events to deliver the information between threads.
    J-P Nurmi

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

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

    Ok, but the second thread must be wait for messagebox reply! How?

  6. #6
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

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

    Well, it depends pretty much how the thread is running. Is it running an event loop or is everything done in QThread::run()? You could start with taking a look at the thread examples shipped with Qt.
    J-P Nurmi

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

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

    It's not implemented yet! I think, in QThread:run()! Is the event loop better?

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    IMO eventually you'll have to use a wait condition to put the waiting thread to sleep. And the message box would have to be shown using show() and not exec(), otherwise it'll block the main thread execution which makes all the situation with using another thread highly doubtfull.

    To me it smells a little like a bad design somewhere...

  9. #9
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

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

    Just curious, what is the thread actually processing?
    J-P Nurmi

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

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

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

  11. #11
    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 00:54. Reason: wrapped too long lines

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

    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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.