Results 1 to 11 of 11

Thread: Receiving QMousePressEvents above QPushButton in the parrent widget

  1. #1
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Receiving QMousePressEvents above QPushButton in the parrent widget

    Hi,
    I'm trying to move a frameless widget with the mouse. It works well if the mouse is on a line edit or on the widget itself, but doesn't work well on a button and not at all on a deactivated button. I've attached a screenshot of the widget.

    I've reimplemented mousePressEvent() and mouseMoveEvent() in the widget. The first one is for getting the mouse position (otherwise the widget would jump to the mouse position) and the second is for actually moving the widget.

    I have to problems with the PushButtons:
    On the activeted one I'm getting a mouseMoveEvent but not mousePressEvent. So the widget is still jumping if you grab it at a push button. I've figured out, that I can reimplement the mousePressEvent() method in the QPushButton. But then I would have to compute the position of the widget, add it to the local position and finaly send it to the parent. That's a little bit of work and I don't think it is the best way to do it.

    On the deactiveted push buttons I even don't get a mouseMoveEvent. Do I realy have to reimplement the QPushButton::event() method? Shouldn't it be possible to handle these events in the parent object/widget?
    Attached Images Attached Images
    Attached Files Attached Files

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Sounds like you need an event filter for the widgets.
    You could install the frameless, parent widget as event filter for all its children and catch mouse events in there, but if you have a lot of widgets that won't look pretty.

    Maybe you can do something with QCoreApplication::setEventFilter, but that's a bit harder to implement.

  3. #3
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    As of my understanding an eventFilter can only block events, but not redirect them. I've tried already eventFilters on the pushbuttons and the main widget in various combinations, but they didn't work as i want (probably i haven't understood them correctly). Could you kindly say exactly what i should do?

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Well, not necessarily block them. Just acknowledge them. Think of it as a way for the frameless widget to know that mouse was pressed or moved somewhere inside it.
    So there is no need to block them, just let them pass through, but also do something specific: move the widget.

    The mouse coordinates can be extracted from the event itself, so you need only a function in the frameless widget that moves it. You can call it from the event filter for every mouse move event that you get. As for the rest, just call the base class version of eventFilter, don't interfere with the events.

  5. The following user says thank you to marcel for this useful post:

    aMan (19th September 2007)

  6. #5
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Qt Code:
    1. BinCalc::BinCalc(QWidget *parent) {
    2. ..
    3. pushButton_0->installEventFilter(this);
    4. }
    5.  
    6. bool BinCalc::eventFilter(QObject* watched, QEvent* event) //BinCalc is the frameless widget
    7. {
    8. if(event->type()==QEvent::MouseButtonPress) {
    9. QPoint posInPushButton=dynamic_cast<QMouseEvent*>(event)->pos();
    10. QPoint posOfPushButton=dynamic_cast<QWidget*>(watched)->pos();
    11. m_moveStartPos=posInPushButton+posOfPushButton;
    12. }
    13.  
    14. return QWidget::eventFilter(watched, event);
    15. }
    To copy to clipboard, switch view to plain text mode 

    This code works but is very slow (It flickers when moving. This doesn't happen when moving with the line edit.) Is there a possibility to make it faster?

    edit: I've noticed, that the button isn't activated (it doesn't get the event). So it doesn't work
    edit2: it is activated, but it has no animation
    Last edited by aMan; 19th September 2007 at 22:27.

  7. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    I'm not sure.
    Can you post the part where you move the widget and how do you call it?

  8. #7
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Sure
    Qt Code:
    1. void BinCalc::mouseMoveEvent(QMouseEvent* event) {
    2. move(event->globalX()-m_moveStartPos.x(),
    3. event->globalY()-m_moveStartPos.y());
    4. }
    5.  
    6. void BinCalc::mousePressEvent(QMouseEvent* event) {
    7. m_moveStartPos = event->pos();
    8. QWidget::mousePressEvent(event);
    9. }
    To copy to clipboard, switch view to plain text mode 

  9. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    You're moving the widget for every move event.
    try adding a boolean flag in your class. Set it to true when the mouse button is pressed and to false on release.

    In mouse move event, move the widget only if the flag is true.

    edit: I've noticed, that the button isn't activated (it doesn't get the event). So it doesn't work
    edit2: it is activated, but it has no animation
    That's not normal. It should get the events and behave normal.

  10. #9
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Quote Originally Posted by marcel View Post
    You're moving the widget for every move event.
    try adding a boolean flag in your class. Set it to true when the mouse button is pressed and to false on release.

    In mouse move event, move the widget only if the flag is true.
    Are you sure? If mouse tracking is of, mouseMoveEvent is only called if the button is pressed.

  11. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    I don't trust mouse tracking . Well of course it gets called only when the button is press, I just forget that.

    Anyway, you get flicker because you m_moveStartPos is in local widget coordinates. It should also be in global coordinates.

    Somewhere in the QWidget documentation it is stated that when performing moves, the passed coordinates should be global, to avoid flicker.

  12. #11
    Join Date
    Jul 2006
    Posts
    79
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving QMousePressEvents above QPushButton in the parrent widget

    Thank you for you help, problem solved. I had to add the mouse move event to the filter too.

    Qt Code:
    1. bool BinCalc::eventFilter(QObject* watched, QEvent* event)
    2. {
    3. if(event->type()==QEvent::MouseButtonPress) {
    4. QPoint posInPushButton=dynamic_cast<QMouseEvent*>(event)->pos();
    5. QPoint posOfPushButton=dynamic_cast<QWidget*>(watched)->pos();
    6. m_moveStartPos=posInPushButton+posOfPushButton;
    7. }
    8. else if(event->type()==QEvent::MouseMove) {
    9. mouseMoveEvent(dynamic_cast<QMouseEvent*>(event));
    10. }
    11.  
    12. return QWidget::eventFilter(watched, event);
    13. }
    To copy to clipboard, switch view to plain text mode 

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
  •  
Qt is a trademark of The Qt Company.