Results 1 to 6 of 6

Thread: Popup Menu not closing after clicking custom widget

  1. #1
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Popup Menu not closing after clicking custom widget

    I have a QMenu that contains one QActionWidget. The QActionWidget contains a custom QWidget (CSpinBoxWidget), which comprises a QSpinBox and a custom QPushButton (CTitleButton).

    When the CTitleButton is clicked I would like the QMenu to close.

    I read here that I will most likely need to do something with the handling of mouseReleaseEvent. I decided to use a QPushButton, but I did try with a QToolButton and couldn't get it working.

    When the CTitleButton is clicked, CTitleButton::mouseReleaseEvent gets called. Then the event is passed to the parent of the CTitleButton, which is the CSpinBoxWidget.

    Note: I tried connecting CSpinBoxWidget::titleClicked [signal] to QActionWidget::trigger [slot], but this didn't help.

    Qt Code:
    1. class CTitleButton : public QPushButton
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. CTitleButton(QWidget* parent = 0) : QPushButton(parent) {}
    7. void mouseReleaseEvent(QMouseEvent* event) {
    8. QPushButton::mouseReleaseEvent(event);
    9. QWidget::mouseReleaseEvent(event);
    10. }
    11. };
    12.  
    13. class CSpinBoxWidget : public QWidget
    14. {
    15.  
    16. Q_OBJECT
    17.  
    18. public:
    19. CSpinBoxWidget(const QString& t, QWidget* parent = 0) :
    20. QWidget(parent)
    21. {
    22. value = new QSpinBox(parent);
    23. value->setContextMenuPolicy(Qt::NoContextMenu);
    24.  
    25. title = new CTitleButton(parent);
    26. title->setText(t);
    27.  
    28. QHBoxLayout* hLayout = new QHBoxLayout(parent);
    29. hLayout->addWidget(title);
    30. hLayout->addWidget(value);
    31. hLayout->setSpacing(2);
    32. hLayout->setMargin(2);
    33. setLayout(hLayout);
    34.  
    35. // When the title button is clicked
    36. connect(title, SIGNAL(clicked()),
    37. this, SIGNAL(titleClicked()));
    38. }
    39. ~CSpinBoxWidget() {}
    40.  
    41. public:
    42. int Value() { return value->value(); }
    43. void SetValue(int val) { value->setValue(val); }
    44. void SetMinimum(int min) {
    45. value->setMinimum(min);
    46. }
    47. void SetMaximum(int max) {
    48. value->setMaximum(max);
    49. }
    50.  
    51. signals:
    52. void titleClicked();
    53.  
    54. private:
    55. void mouseReleaseEvent(QMouseEvent* e) {
    56. QWidget::mouseReleaseEvent(e);
    57. }
    58.  
    59. private:
    60. QSpinBox* value;
    61. QPushButton* title;
    62. };
    To copy to clipboard, switch view to plain text mode 

    But I don't understand how the event handling is supposed to work. When I create the QMenu, QWidgetAction and CSpinBox widget, does it matter who is whose parent as far as the event handling goes?

    "QWidget::mouseReleaseEvent(event);" in CTitleButton::mouseReleaseEvent(QMouseEvent* event) ends up calling "event->ignore();", so does nothing really.

    There is a documentation snippet in qwidgetaction.cpp that reads:

    Note that it is up to the widget to activate the action, for example by reimplementing mouse event handlers and calling QAction::trigger().
    But this doesn't make sense to me. How does the widget activate the action? Which mouseReleaseEvent functions need to be reimplemented? Who needs to call QAction::trigger (could only be derived QWidgetAction or QMenu)?

    Any ideas?

    Stefan
    Last edited by stefanadelbert; 15th April 2010 at 04:51.

  2. #2
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Popup Menu not closing after clicking custom widget

    QMenu is receiving the mouseReleaseEvent, but is doing nothing with it.

    d->mouseDown != this resolves to true so
    Qt Code:
    1. d->mouseDown = 0;
    2. return;
    To copy to clipboard, switch view to plain text mode 
    is being run.

    Here is QMenu::mouseReleaseEvent (see qmenu.cpp):
    Qt Code:
    1. void QMenu::mouseReleaseEvent(QMouseEvent *e)
    2. {
    3. Q_D(QMenu);
    4. if (d->aboutToHide || d->mouseEventTaken(e))
    5. return;
    6. if(d->mouseDown != this) {
    7. d->mouseDown = 0;
    8. return;
    9. }
    10.  
    11. d->mouseDown = 0;
    12. d->setSyncAction();
    13. QAction *action = d->actionAt(e->pos());
    14.  
    15. if (action && action == d->currentAction) {
    16. if (action->menu())
    17. action->menu()->d_func()->setFirstActionActive();
    18. else {
    19. #if defined(Q_WS_WIN)
    20. //On Windows only context menus can be activated with the right button
    21. if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
    22. #endif
    23. d->activateAction(action, QAction::Trigger);
    24. }
    25. } else if (d->hasMouseMoved(e->globalPos())) {
    26. d->hideUpToMenuBar();
    27. }
    28. }
    To copy to clipboard, switch view to plain text mode 

    Does this mean that the menu thinks that it wasn't actually clicked? What does d->mouseDown actually represent?

  3. #3
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Popup Menu not closing after clicking custom widget

    A simplistic look at this, but will connecting the titleClicked() signal to the QMenu::hide() slot not work?

  4. The following user says thank you to norobro for this useful post:

    stefanadelbert (15th April 2010)

  5. #4
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Popup Menu not closing after clicking custom widget

    Sometimes simple is best. I'll give that a try and I reckon that it'll do that trick.

    EDIT: Of course that works! Those were a few hours of my life that I won't get back.

    @norobro: thanks

    EDIT: I've been able to remove a fair amount of code now, notably the derived QPushButton with reimplemented mouseReleaseEvent. It would be nice to use the event/action framework as intended, but...
    Last edited by stefanadelbert; 15th April 2010 at 05:11.

  6. #5
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Popup Menu not closing after clicking custom widget

    Glad I could help! You were way over my head delving into the event/action framework. I'm the two S'es of the K.I.S.S. principle.

  7. #6
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Popup Menu not closing after clicking custom widget

    Any idea how I mark a thread as solved or closed?

Similar Threads

  1. Popup Menu
    By kavinsiva in forum Newbie
    Replies: 2
    Last Post: 25th September 2009, 10:09
  2. Custom menu widget
    By shadowfax in forum Newbie
    Replies: 0
    Last Post: 9th July 2009, 18:30
  3. Replies: 3
    Last Post: 17th May 2009, 20:17
  4. Replies: 4
    Last Post: 13th April 2009, 19:37
  5. Popup menu for a QGraphicsItem?
    By Morea in forum Qt Programming
    Replies: 4
    Last Post: 4th February 2009, 21:27

Tags for this Thread

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.