Results 1 to 10 of 10

Thread: contextMenuEvent has issues since 4.1.3

  1. #1
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default contextMenuEvent has issues since 4.1.3

    Ok, so I have written this application for gentoo Linux that lets users edit the runlevels. In order to do so they have to rightclick custom widgets upon which a QMenu will pop up ... The widget with the active context menu has a red border. I put in the red border to highlight the widget and create a visual distinction between the active widget and the other ones.

    Now, here is the problem: in previous versions, when I rightclicked a widget and then immediately made another rightclick on a second widget, the highlighted borders around the first widget would dissappear along with the Popupmenu and only the second one was highlighted (having the red border). But since I've upgraded qt to 4.1.2/4.1.3 the border of the previous widget will remain highlighted and the contextMenuEvent() will not completely finish, until I do a leftclick etc.

    If I insert some print statements, I see that the contextMenuEvent function will remain unfinished and when the leftclick etc. occurs, all pending contextMenuEvents finish. Since this was not the case with previous versions (I have compiled the app with qt-4.1.0 and there it doesn't have this issue) , I assume that is a bug with qt. Can anybody confirm that or tell me where I am doing something wrong?

    I can post a link to the tarball if you wish.


    Thanx in advance
    momesana

  2. #2
    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: contextMenuEvent has issues since 4.1.3

    Please post a minimal compilable example which reproduces the problem.

  3. #3
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: contextMenuEvent has issues since 4.1.2

    Hi,
    as you requested, below is the minimal code reproducing the issue. Just save it in a directory of its own as "main.h" and execute qmake -project && qmake && make . Try this with Qt version <= Qt-4.1.1 and >=Qt-4.1.2 to see the difference in behaviour.

    Qt Code:
    1. #include <QApplication>
    2. #include <QWidget>
    3. #include <QLayout>
    4. #include <QScrollArea>
    5. #include <QPainter>
    6. #include <QMenu>
    7. #include <QContextMenuEvent>
    8. #include <QAction>
    9. #include <iostream>
    10.  
    11. // --------------- WIDGET ---------------- //
    12.  
    13. class Widget : public QWidget
    14. {
    15. Q_OBJECT
    16. public:
    17. Widget();
    18. protected:
    19. void contextMenuEvent(QContextMenuEvent *event);
    20. void paintEvent(QPaintEvent * event);
    21. private:
    22. bool contextM;
    23. };
    24.  
    25.  
    26. Widget::Widget() : QWidget()
    27. {
    28. contextM = false;
    29. }
    30.  
    31. void Widget::paintEvent(QPaintEvent *event)
    32. {
    33. QPainter p(this);
    34. p.setRenderHint(QPainter::Antialiasing);
    35. contextM ? p.setPen(QColor(255,0,0)) : p.setPen(QColor(120,120,120)) ;
    36. p.drawRoundRect(QRectF(1,1,width()-2,height()-2), 2, 40);
    37. }
    38.  
    39. void Widget::contextMenuEvent (QContextMenuEvent *event)
    40. {
    41. contextM = true;
    42. update();
    43.  
    44. QMenu contextMenu;
    45. QAction *act = new QAction( "Dummy Action" ,this);
    46. contextMenu.addAction(act);
    47. contextMenu.exec(event->globalPos());
    48.  
    49. std::cout << ": contextMenu.exec() just finished" << std::endl;
    50.  
    51. contextM = false;
    52. update();
    53. }
    54.  
    55. // -------------- WIDGETS ---------------- //
    56.  
    57. class Widgets : public QScrollArea
    58. {
    59. public:
    60. Widgets();
    61. private:
    62. QVBoxLayout *layout;
    63. };
    64.  
    65. Widgets::Widgets() : QScrollArea()
    66. {
    67. resize(600,100);
    68. QWidget *w = new QWidget(this);
    69. setWidget(w);
    70. setWidgetResizable(true);
    71.  
    72. layout = new QVBoxLayout(w);
    73. layout->addWidget(new Widget);
    74. layout->addWidget(new Widget);
    75. }
    76.  
    77. int main(int argc, char* argv[])
    78. {
    79. QApplication app(argc, argv);
    80. Widgets mw;
    81. mw.show();
    82. return app.exec();
    To copy to clipboard, switch view to plain text mode 
    }

    thanx in advance
    momesana

  4. #4
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: contextMenuEvent has issues since 4.1.2

    Ok, I tested the code with following selfcompiled versions of Qt:
    4.0.1
    4.1.0
    4.1.1
    4.1.2
    4.1.3

    All versions prior to 4.1.3 had the previous behaviour, which is not perfect either. With those version doing the second rightclick will close the first context menu (exit the contextMenuEvent function) but will not enter the second contextMenuEvent on the current clicked widget. This way, you end up clicking twice in order to get the second context menu. This is a little annoying. The approach with 4.1.3 is more convinient from this perspective since doing the second rightlick will close the first contextMenu and open the second one so there is only one click required. On the other hand, there is this issue with the first contextMenuEvent not completely finishing ...

    I'd really appreciate it if someone tells me what I'm doing wrong. Right now, my workaround is pretty ugly. The contextMenuEvent emits a signal that is connected to a removeHighlight() slot in the parent widget. The parentwidget then searches through all child widgets and gives asks them to remove their highlighted borders if they are not the active widget. It works but is quite ugly...

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: contextMenuEvent has issues since 4.1.3

    Qt Code:
    1. bool Widget::eventFilter( QObject *obj, QEvent *event )
    2. {
    3. QMenu *menu = qobject_cast< QMenu* >( obj );
    4. if( menu != 0 && event->type() == QEvent::Hide ) {
    5. menu->deleteLater();
    6. contextM = false;
    7. update();
    8. }
    9. return QWidget::eventFilter( obj, event );
    10. }
    11.  
    12. void Widget::contextMenuEvent ( QContextMenuEvent *event )
    13. {
    14. ...
    15. QMenu *contextMenu = new QMenu();
    16. contextMenu->installEventFilter( this );
    17. ...
    18. contextMenu->popup( event->globalPos() );
    19. }
    To copy to clipboard, switch view to plain text mode 
    Instead of using an event filter, you can subclass QMenu and make it emit a signal when it's hidden.

  6. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: contextMenuEvent has issues since 4.1.3

    Quote Originally Posted by jacek
    Qt Code:
    1. bool Widget::eventFilter( QObject *obj, QEvent *event );
    2. ...
    To copy to clipboard, switch view to plain text mode 
    Thank you very much. It worked pretty well. Anyway, isn't that a bug in Qt? Shouldn't it do that automatically without an eventhandler?

    thanx
    momesana

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: contextMenuEvent has issues since 4.1.3

    Quote Originally Posted by momesana
    Shouldn't it do that automatically without an eventhandler?
    What should it do automatically? Set your contextM variable to false?

    You want to perform an action when the popup menu is hidden and normally Qt doesn't send any signal when this happens. That's why you have to use an event filter or subclass QMenu.

  8. #8
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: contextMenuEvent has issues since 4.1.3

    Quote Originally Posted by jacek
    What should it do automatically? Set your contextM variable to false?
    That's not what I mean. I have programmed the contextMenuEvent in a way that it sets contextM to false and calls update when the QMenu::exec()/QMenu:: popup() returns. When I rightclick on another widget, and the QMenu of the previous highlighted Widget dissapears and the new one pops up, I really expect that the first QMenu::exec() returns so the contextM is set to true and update() is called. What bothers me, is that the QMenu::exec() does not really return in this case. Its a mere hiding of the QMenu hindering the contextM variable to be set to false in the frist place. until I do a left click etc, after which the popup()/exec() really exits.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: contextMenuEvent has issues since 4.1.3

    Quote Originally Posted by momesana
    I really expect that the first QMenu::exec() returns so the contextM is set to true and update() is called. What bothers me, is that the QMenu::exec() does not really return in this case.
    You're right, it would be nice if QMenu::exec() would return immediately after the menu is hidden. Maybe you should send your example program to the Trolls?

  10. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: contextMenuEvent has issues since 4.1.3

    Quote Originally Posted by jacek
    You're right, it would be nice if QMenu::exec() would return immediately after the menu is hidden. Maybe you should send your example program to the Trolls?
    I wanted to do that a few days ago, but then I was not sure, whether I am doing something wrong myself. But I will file a bug report now.

    Thank you

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.