Results 1 to 6 of 6

Thread: MousePressEvent on Widget stops event propagation

  1. #1
    Join Date
    Jul 2011
    Posts
    42
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question MousePressEvent on Widget stops event propagation

    Hi,
    I have built a custom combo box, its basically a Widget with 2 buttons. Clicking on any of them displays another widget below them, showing the combo.
    This combo displays the items with a Tree View, This is used to display an AddressBar, where the main/root items are the names of the contacts and the subitems (childs) are the several emails of each person.

    The thing is that in order to simulate the QComboBox behaviour, the combo must disappear when the user clicks outside or when clicking on the buttons again.

    For the combo i have used a Widget as a wrapper for the TreeView, applying the Qt::Popup flag. That didnt help. Popup widgets by default get hidden when clicking outside, but in the case i click on the button, the combo was hidden and as a result of clicking outside of the view, then the click was detected on the button and the view was shown again, since it was not visible. I couldnt hide the view when clicking back on the button.

    What i found out is that: when the QWidget is visible, it get the mouse press event. Checks if the event position is inside it, and if so, hides it. When the widget is hidden, then the click event is detected on the button.
    So i overrided the implementation of MousePressEvent in the QWidget that wrapps the QTreeView to play a little, copying exactly what QWidget does, and i found that if i DONT hide the QWidget on the mousePressEvent, then the click is NOT detected on the button.

    Is it possible that the MousePressEvent is not propagating the event when the QWidget is visible? The QWidget has no parent at all, but when hidden by the mouse click, the event is informed to the button.

    Any ideas?
    Thanks

  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: MousePressEvent on Widget stops event propagation

    The second half of your post is somewhat unclear (to many "it" in one sentence, I guess...). You want the event to be propagated or not? And in what conditions? If you override some event handler and don't call ignore() then the event is accepted and no propagation occurs. I don't know if that answers your question...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jul 2011
    Posts
    42
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MousePressEvent on Widget stops event propagation

    mmm yeah i had a hard time trying to make it clear.

    The thing is: if i click on the button, i want the QWidget that handles the view, NOT to be hidden because of an outside click, and handle the click event on the button.
    i tried several combinations of ignore, accept. I also tried verifying the position of the click, and only hiding the QWidget if the position didnt include the view nor the button. In that case the view wasnt hidden, but the button never got the click event.

    Somehow when the QWidget that is catching the mouse events on the MousePressEvent, is not hidden, the event doesnt propagate. It only escalates if i hide the widget.

    Is it clearer now?
    Thanks!

  4. #4
    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: MousePressEvent on Widget stops event propagation

    I'm still not clear what the problem is. Qt::Popup works in such a way that the widget gets hidden regardless where you click if you click outside the widget area and I don't think there is anything you can do about it. The event won't propagate anywhere because the popup widget doesn't have a parent. The only thing you can do is to install the event filter on the popup, detect that the click happens outside the widget area and at that moment post another event to the widget under the cursor, letting the original event close the popup.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jul 2011
    Posts
    42
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MousePressEvent on Widget stops event propagation

    I created a custom QWidget, that is NOT a qt::Popup, i overrided the MousePressEvent and put the same logic that the QWidget has in that method.
    The source code of the QWidget hides the widget only if the click was made outside the widget's QRect.

    And it is a fact that when i click on the button , the event is first catched on the MousePressEvent of the widget. If i hide the widget in that method, then the button recieves the click event. If i DONT hide the widget, then the button doesnt get the click event.

    this is the overriden method:

    Qt Code:
    1. void PrivateView::mousePressEvent(QMouseEvent *event)
    2. {
    3. //LoggerManager::LogDebug("[PrivateView::mousePressEvent] press event");
    4. event->accept();
    5. QWidget* w;
    6. while ((w = QApplication::activePopupWidget()) && w != this)
    7. {
    8. w->close();
    9. if (QApplication::activePopupWidget() == w) // widget does not want to dissappear
    10. {
    11. w->hide(); // hide at least
    12. }
    13. }
    14.  
    15. QPoint source = mapToGlobal(event->pos());
    16. //check if the click is outside the widget and the button
    17. if (source.x() >= this->x()
    18. && source.x() <= (this->x() + this->width())
    19. && source.y() >= (this->y() - btnHeight)
    20. && source.y() <= (this->y() + this->height()) )
    21. {
    22. // the click was made inside the widget or inside the button
    23. }
    24. else
    25. {
    26. hide();
    27. }
    28.  
    29. }
    To copy to clipboard, switch view to plain text mode 


    Added after 1 58 minutes:


    So here's a slight modification. Here you'll see that im filtering the mouse press event, when the click was made inside or in the button, then we dont hide it and ignore the event. Otherwhise we hide the view and accept the event.

    Qt Code:
    1. void PrivateView::mousePressEvent(QMouseEvent *event)
    2. {
    3. //LoggerManager::LogDebug("[PrivateView::mousePressEvent] press event");
    4. QWidget* w;
    5. while ((w = QApplication::activePopupWidget()) && w != this)
    6. {
    7. //LoggerManager::LogDebug("[PrivateView::mousePressEvent] hide: " + w->objectName());
    8. w->close();
    9. if (QApplication::activePopupWidget() == w) // widget does not want to dissappear
    10. {
    11. w->hide(); // hide at least
    12. }
    13. }
    14.  
    15. QPoint source = mapToGlobal(event->pos());
    16. QPoint viewGlobalPoint = this->pos();//mapToGlobal(this->pos());
    17.  
    18. //check if the click is outside the widget and the button
    19. if (source.x() >= viewGlobalPoint.x()
    20. && source.x() <= (viewGlobalPoint.x() + 200)
    21. && source.y() >= (viewGlobalPoint.y() - 25)
    22. && source.y() <= viewGlobalPoint.y())
    23. {
    24. // the click was made inside the button
    25. event->ignore();
    26. //hide(); --> if uncomment this, then the button recieves the click event
    27. qDebug() << "click in the button area -> Do not hide, and ignore event";
    28. }
    29. else if (this->rect().contains(event->pos()))
    30. {
    31. // the click was made inside the widget
    32. event->ignore();
    33. qDebug() << "click inside view -> Do not hide, and ignore event";
    34. }
    35. else
    36. {
    37. event->accept();
    38. hide();
    39. emit clickOutside(source);
    40. qDebug() << "hides the view, and accepts event";
    41. }
    42. }
    To copy to clipboard, switch view to plain text mode 

    In this case eventhough i ignore the event, the button doesnt recieve the click event. If i add the "hide()" in that block, then the button recieves the event.
    Why is that happening? shouldnt the button recieve the event allways? why is the visible state of the widget interfering in the event procesing?

    Thanks for your help!
    Last edited by superpacko; 7th July 2011 at 17:06. Reason: reformatted to look better

  6. #6
    Join Date
    Jul 2011
    Posts
    42
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MousePressEvent on Widget stops event propagation

    anyone? any ideas?

Similar Threads

  1. Event propagation-Windows key special case
    By hanumanth in forum Qt Programming
    Replies: 0
    Last Post: 16th April 2010, 15:46
  2. Event propagation direction
    By spraff in forum Qt Programming
    Replies: 0
    Last Post: 6th December 2008, 21:03
  3. Graphics View Event Propagation
    By pherthyl in forum Qt Programming
    Replies: 10
    Last Post: 3rd July 2008, 10:39
  4. Replies: 1
    Last Post: 16th October 2007, 22:41
  5. How to prevent Event Propagation to Parent?
    By viking in forum Qt Programming
    Replies: 6
    Last Post: 9th May 2007, 06:29

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.