Results 1 to 1 of 1

Thread: QMessageBox on Linux fails to gain focus

  1. #1
    Join Date
    Apr 2011
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QMessageBox on Linux fails to gain focus

    There are several topics that are duplicates to this forum thread:
    qtforum, qtcentre-0, qtcentre-1, qtcentre-2, but this one differs in one aspect. Here's the problem:
    1) You have a simple widget containing a push button.
    2) Closing the widget and pushing the button causes a QMessageBox to appear.
    3) Run the widget and immediately after that close it. The QMessageBox is displayed and HAS focus.
    4) Run the widget again, move it or click the button. Then close it again - again the message box appears but this time it HAS NO focus.

    And the difference:
    ~~~~~~~~~~~~
    Note that the QMessageBox that is displayed inactive is the one shown in an overriden closeEvent(QCloseEvent*) member function. The message box that is shown when the button is clicked is always active e.g. always has focus.

    This problem is reproduced only on Linux environment. Since it is not reproduced on Windows is it a Qt framework's bug? What is so special about this closeEvent that when it is fired the shown QMessageBox is inactive and has no focus on Linux?
    ~~~~~~~~~~~~

    Probable solution:
    ~~~~~~~~~~~
    Instead of using the static member functions for creating a warning, question or information message boxes, a good beginning to the solution is to create a QMessageBox object, make some adjustments to it, and then display it.

    Currently nothing has helped the QMessageBox to gain focus, none of the following:
    1) Try not to set parent to the QMessageBox being displayed.
    2) Use setFocus.
    3) Use setWindowState( Qt::WindowActive ). Some form members say that setting the window state to Qt::WindowFullScreen solves the problem. Doing this way the message box neither becomes enabled nor it is displayed correctly.
    4) Use grabKeyboard and releaseKeyboard.

    Fully reproduce the problem:
    ~~~~~~~~~~~~~~~~~~
    Create a simple Qt GUI project with QWidget base class without generating .ui file (remove the checkmark in the project creation wizard) and paste the code below in the .cpp and .h files of the QWidget inherited class.

    -----------------------------------------------------------------
    Widget.cpp
    Qt Code:
    1. #include "Widget.h"
    2. #include <QCloseEvent>
    3. #include <QMessageBox>
    4. #include <QPushButton>
    5. #include <QGridLayout>
    6.  
    7. Widget::Widget(QWidget *parent)
    8. : QWidget(parent)
    9. {
    10. QGridLayout* const gl = new QGridLayout( this );
    11.  
    12. QPushButton* const pb = new QPushButton("Show Message Box...");
    13. gl->addWidget( pb );
    14.  
    15. connect( pb, SIGNAL(clicked()), this, SLOT(showMessageBox()) );
    16. }
    17.  
    18. Widget::~Widget()
    19. {
    20. }
    21.  
    22. void Widget::closeEvent(QCloseEvent* event)
    23. {
    24. const int buttonId = QMessageBox::warning( this, "Warning", "Close Event", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok );
    25.  
    26. if ( QMessageBox::Cancel == buttonId )
    27. {
    28. event->ignore();
    29. }
    30. }
    31.  
    32. void Widget::showMessageBox()
    33. {
    34. const int buttonId = QMessageBox::warning( this, "Warning", "Button click", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok );
    35. Q_UNUSED( buttonId )
    36. }
    To copy to clipboard, switch view to plain text mode 

    Widget.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QtGui/QWidget>
    5.  
    6. class Widget : public QWidget
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. Widget(QWidget *parent = 0);
    12. ~Widget();
    13.  
    14. protected:
    15. virtual void closeEvent(QCloseEvent* event);
    16.  
    17. private slots:
    18. void showMessageBox();
    19. };
    20.  
    21. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 
    -----------------------------------------------------------------


    Added after 20 minutes:


    Noticed that when the widget is created if the user tries to close it for the first time - the message box that is shown is active. Try to close the widget for a second time - the displayed message box is inactive. The focus state of the QMessageBox on close is governed by the times you try to close the widget. The focus state has nothing to do with that whether you move the window or whether you click inside of the window before closing the widget.


    Added after 41 minutes:


    Another version of the code above, this time using an instance of QMessageBox object:

    Widget.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QtGui/QWidget>
    5.  
    6.  
    7. class Widget : public QWidget
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. Widget(QWidget *parent = 0);
    13. ~Widget();
    14.  
    15. protected:
    16. virtual void closeEvent(QCloseEvent* event);
    17.  
    18. private slots:
    19. void showMessageBox();
    20.  
    21. private:
    22. QMessageBox* m_messageBox;
    23. };
    24.  
    25. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

    Widget.cpp
    Qt Code:
    1. #include "Widget.h"
    2. #include <QCloseEvent>
    3. #include <QMessageBox>
    4. #include <QPushButton>
    5. #include <QGridLayout>
    6.  
    7. Widget::Widget(QWidget *parent)
    8. : QWidget(parent)
    9. , m_messageBox(0)
    10. {
    11. QGridLayout* const gl = new QGridLayout( this );
    12.  
    13. QPushButton* const pb = new QPushButton("Show Message Box...");
    14. gl->addWidget( pb );
    15.  
    16. connect( pb, SIGNAL(clicked()), this, SLOT(showMessageBox()) );
    17.  
    18. m_messageBox = new QMessageBox( QMessageBox::Warning, "Warning", "Close event or button click!", QMessageBox::Ok | QMessageBox::Cancel, this );
    19. }
    20.  
    21. Widget::~Widget()
    22. {
    23. }
    24.  
    25. void Widget::closeEvent(QCloseEvent* event)
    26. {
    27. const int buttonId = m_messageBox->exec();
    28.  
    29. if ( QMessageBox::Cancel == buttonId )
    30. {
    31. event->ignore();
    32. }
    33. }
    34.  
    35. void Widget::showMessageBox()
    36. {
    37. const int buttonId = m_messageBox->exec();
    38. Q_UNUSED( buttonId )
    39. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by napajejenunedk0; 9th May 2011 at 13:12. Reason: updated contents

Similar Threads

  1. QMessageBox Key focus
    By mickeyk191 in forum Qt Programming
    Replies: 1
    Last Post: 14th April 2010, 10:12
  2. QMessageBox with no focus
    By mpi in forum Qt Programming
    Replies: 0
    Last Post: 27th September 2009, 16:52
  3. QMessageBox and Focus
    By fruzzo in forum Qt Programming
    Replies: 3
    Last Post: 18th November 2008, 19:39
  4. Qt 4.1.2 Fails to build on Linux
    By rohandhruva in forum Installation and Deployment
    Replies: 6
    Last Post: 16th April 2006, 21:44
  5. gcc (linux) : ok ; g++ (windows) : fails
    By nouknouk in forum Qt Programming
    Replies: 1
    Last Post: 25th February 2006, 03:08

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.