Results 1 to 20 of 25

Thread: Move Rectangle on mouse Move

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Move Rectangle on mouse Move

    Hi guys,
    Well, I have some objects on QFrame in form of rectangles( either one or more ). I have options to copy and paste the objects. I say CTRL+C to copy the object and say CTRL+V to paste. While moving the mouse after pressing CTRL+V, I want the rectangular object be seen whereever I move the mouse ( giving a feeling to user that something is about to paste inside QFrame).
    In qt3 I could do this with no efforts as there was RasterOp and painting could be done from anywhere but in Qt4 I'm having problem to achieve the same result.

    I have written a sample program which will help to get what I mean.

    In the sample program, Click on paste button, a rectangle should appear at the tip of mouse pointer. Now if I move mouse, the rectangle should move along with the mouse pointer. I tried but could not succeed.

    Here qApp->enter_loop() is QT3 support class as I couldnt find the alternative in Qt4.

    Qt Code:
    1. RubberBand::RubberBand(QWidget *parent, Qt::WFlags flags)
    2. : QWidget(parent, flags){
    3. setAutoFillBackground( true );
    4. QPalette palette;
    5. palette.setColor(backgroundRole(), QColor(Qt::white) );
    6. setPalette(palette);
    7.  
    8. QPushButton* btnPaste = new QPushButton("Paste", this);
    9. btnPaste->setGeometry( 250, 250, 30, 40 );
    10. connect( btnPaste, SIGNAL( clicked() ), this, SLOT( onPasteBtn() ) );
    11. m_Rubberband = 0;
    12. }
    13.  
    14. RubberBand::~RubberBand()
    15. {}
    16.  
    17. void RubberBand::onPasteBtn(){
    18. qApp->installEventFilter( this );
    19. qApp->enter_loop();
    20. }
    21.  
    22. bool RubberBand::eventFilter( QObject *obj, QEvent *e ){
    23. if ( e->type() == QEvent::KeyPress && ((QKeyEvent *)e)->key() == Qt::Key_Escape ){
    24. // remove this event filter and exit the current event loop
    25. qApp->removeEventFilter( this );
    26. qApp->exit_loop();
    27. delete m_Rubberband;
    28. m_Rubberband = 0;
    29. return TRUE;
    30. }
    31. if( e->type() == QEvent::MouseMove ){
    32. m_pasteRect.setTop( ((QMouseEvent *)e)->pos().x() );
    33. m_pasteRect.setLeft( ((QMouseEvent *)e)->pos().y() );
    34.  
    35. m_pasteRect.setBottom( ((QMouseEvent *)e)->pos().x() + 50 );
    36. m_pasteRect.setRight( ((QMouseEvent *)e)->pos().y() + 50 );
    37.  
    38. if( !m_Rubberband )
    39. m_Rubberband = new QRubberBand(QRubberBand::Rectangle, this);
    40.  
    41. //qDebug() << ((QMouseEvent *)e)->pos().x() << ((QMouseEvent *)e)->pos().y();
    42.  
    43. m_Rubberband->setGeometry( m_pasteRect );
    44. m_Rubberband->show();
    45.  
    46. return TRUE;
    47. }
    48. else if( e->type() == QEvent::MouseButtonRelease ){
    49. // remove this event filter and exit the current event loop
    50. qApp->removeEventFilter( this );
    51. qApp->exit_loop();
    52. delete m_Rubberband;
    53. m_Rubberband = 0;
    54. return TRUE; // eat event
    55. }
    56. return TRUE; // block standard event processing
    57. }
    To copy to clipboard, switch view to plain text mode 

    Thanks

  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: Move Rectangle on mouse Move

    Instead of enter_loop, use processEvents() although you don't need it.

    I didn't get to test your example, but take a look at:
    Qt Code:
    1. void Widget::mousePressEvent(QMouseEvent *event)
    2. {
    3. origin = event->pos();
    4. if (!rubberBand)
    5. rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    6. rubberBand->setGeometry(QRect(origin, QSize()));
    7. rubberBand->show();
    8. }
    9.  
    10. void Widget::mouseMoveEvent(QMouseEvent *event)
    11. {
    12. rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
    13. }
    14.  
    15. void Widget::mouseReleaseEvent(QMouseEvent *event)
    16. {
    17. rubberBand->hide();
    18. // determine selection, for example using QRect::intersects()
    19. // and QRect::contains().
    20. }
    21.  
    22. [COLOR=#000000][FONT=Courier New,courier][/FONT][/COLOR]
    To copy to clipboard, switch view to plain text mode 
    This is how your code should look(more or less)! Use specialized event handlers, it is easier and more clear!

    I will test it as soon as I get the chance.

    Anyway, are you trying to display the rubber band outside it's parent? If so, it will not work. Try passing NULL for parent when you create the QRubberBand.

    regards

  3. #3
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Move Rectangle on mouse Move

    Hi marcel,
    I know that example.

    I think I was not clear what I said.

    I dont want to draw a rubberband on mouseClick and enlarge the rubberband on mouse Release. I dont know how to explain but I'll try.

    Just run the sample program. Click 'paste'. Now what I want is a rectangle. The top left of rectangle should be on mousePointer. Now when I move the mouse I want the rectangle too to move along with the mousePointer. I use eventFilter coz it is a continous loop until the user releases the mouse where I exit the loop.

    Ok I ask you one question. If your user copies some objects (say a polygon) on screen then he/she wants to paste that object some other place on same screen. How do you make sure that the object is copied and is now ready for paste (giving a feeling to user that something is about to paste inside screen)?????Such that when he/she releases the mouse the object gets pasted
    Last edited by vermarajeev; 9th May 2007 at 13:52.

  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: Move Rectangle on mouse Move

    I know what you are trying to do. But you don't do it correctly.
    You could modify that example to fit your need.
    In mouseMoveEvent, just set the correct geometry.

    I use eventFilter coz it is a continous loop until the user releases the mouse where I exit the loop.
    It is a loop anyway, and mouseMoveEvent will get called repeatedly.

    Returning TRUE always in event() is your biggest mistake. You block all the events, like paint() - This is why the QRubberBand doesn't gets painted - it's parent doesn't get a paint event, therefore neither does the rubber band.

    Use the standard event handlers and stop using enter_loop and exit_loop - the Qt event loop works fine, you don't need to force it in doing things.

    Try my suggestion and it will work!

    regards

  5. #5
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Move Rectangle on mouse Move

    How do I fire a MouseMove Event from inside a slot?? Meaning

    Qt Code:
    1. void slotOnPasteButton(){
    2. if( ! computePasteRect() ){ //Gives the reactangular area for object to be pasted
    3. return;
    4. }
    5. // fire or call MouseMove Event
    6. // If the <esc> key is pressed, cancel the pasting operation which I need to check like this
    7. if ( e->type() == QEvent::KeyPress && ((QKeyEvent *)e)->key() == Qt::Key_Escape ) {
    8. //user cancelled paste operation
    9. //clear pasteRect
    10. }
    11. // We have now returned from the mouseMoveEvent, with a new position for the
    12. // bounding box of the objects to be pasted
    13. if( !pasteRect.isNull() )
    14. //do stuffs to paste the object at new position
    15.  
    16. }
    To copy to clipboard, switch view to plain text mode 

  6. #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: Move Rectangle on mouse Move

    You do not activate the events.
    A mouse move event is received whenever you move the mouse over the widget.

    So, mouse move events are always received, given that the mouse is hovered over your widget ( RubberBand ).

    In slotOnPasteButton() all you have to do is create the rubber band( QRubberBand ) and set its initial geometry and show it( like it is done in the mousePressEvent form the example ). The mouseMoveEvent has to test is if the QRubberBand is NULL - if not NULL, then set it's geometry, otherwise, do nothing.

    To test for modifiers use QMOuseEvent::modifiers().

  7. #7
    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: Move Rectangle on mouse Move

    Actually, in mouseMoveEvent, it is better to use QRubberBand::move( e->pos() ) instead of setGeometry.

    How do you know where the user pastes an object? Does he/she have to press a key, or something?
    Because you say "when we return from the mouse move event", but as long as your mouse moves over the widget, you keep getting mouse move events.

  8. #8
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Move Rectangle on mouse Move

    How do you know where the user pastes an object? Does he/she have to press a key, or something?
    He/she has to release the mouse to get new position of object being pasted.

    What if the user wants to cancel the paste operation while moving the mouse or when when the mouse is at still position???

    I'll try out how you said and let you know the status, but do reply me for my questions above coz the user might want to cancel the paste operation anytime....

  9. #9
    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: Move Rectangle on mouse Move

    He/she has to release the mouse to get new position of object being pasted.
    This means that you actually drag the object ( While holding the left button pressed ), so you can use the mouseReleaseEvent to stop dragging and figure out the position where the user dropped the object.

    For this you will have to use keyPressEvent();

  10. #10
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Move Rectangle on mouse Move

    Quote Originally Posted by marcel View Post
    This means that you actually drag the object ( While holding the left button pressed ), so you can use the mouseReleaseEvent to stop dragging and figure out the position where the user dropped the object.
    Not exactly...But something similar. I dont actually drag....

    Ok so far so good. I have got what I want and Marcel it is becuase of your help.Thanks
    Now I have two questions.
    1) As the size of RubberBand rectangle increases, the display becomes very slow. I think the time is delayed because of painting of rubberBand class. Is there a way I can reduce this delay such that I dont have problem moving the rectangle as it becomes large.
    2) As I have other functionalities defined in MouseMove, MousePress, MouseRelease events, not it looks very messy. The idea to include eventFilter was to block all events other than those processed for pasting(mouse moves and clicks). Do you think it was a bad idea????? I know, you think from above post but can you please explain why???

  11. #11
    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: Move Rectangle on mouse Move

    1) As the size of RubberBand rectangle increases, the display becomes very slow. I think the time is delayed because of painting of rubberBand class. Is there a way I can reduce this delay such that I dont have problem moving the rectangle as it becomes large.
    How big are we talking about? And how does the code look now? Maybe it is because of that.

    As I have other functionalities defined in MouseMove, MousePress, MouseRelease events, not it looks very messy. The idea to include eventFilter was to block all events other than those processed for pasting(mouse moves and clicks). Do you think it was a bad idea????? I know, you think from above post but can you please explain why???
    Yes, of course it was a bad idea, because those events are needed.
    You cannot block them, because your application will stop functioning properly.
    For example, when you move the rubberband, your widget also gets repaint events, that tell it to repaint the regions occupied by the rubberband.
    If they are accepted by the event filter, then the rubberband doesn't get any repaint events. Hope you understand now.

    You could scan for all the event types in the eventfilter and print out their name, and then you will actually see how many they are.

Similar Threads

  1. Game mouse movement
    By chaosgeorge in forum Qt Programming
    Replies: 1
    Last Post: 2nd December 2006, 23:41
  2. how to display full tree item name on mouse move ?
    By rajesh in forum Qt Programming
    Replies: 5
    Last Post: 15th November 2006, 08:41
  3. mouse moving don't produce mouse events
    By coralbird in forum Qt Programming
    Replies: 1
    Last Post: 13th September 2006, 06:13
  4. Replies: 2
    Last Post: 24th July 2006, 18:36
  5. QStackerWidget and mouse events
    By high_flyer in forum Qt Programming
    Replies: 3
    Last Post: 25th April 2006, 19:25

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.