Results 1 to 11 of 11

Thread: Color rectangles using QGraphicsRectItem

  1. #1
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Lightbulb Color rectangles using QGraphicsRectItem

    Hi guys, iam stuck in one case. I have scene (using QGraphicsScene) and i fill that scene with squares (using QGraphicsRectItem). I want squares to change their color to black if my mouse button is pressed and if my mouse coursor is over them so i can move my mouse over the whole scene and make every square to change their color to black whenever cursor enters an area of a square and mouse button is pressed. Can you please give me any idea how to make that happen ? I was trying to solve that using mousePressEvent, mouseMoveEvent, dragEnterEvent etc. and I think that this is a proper way to do that but i have no idea how to push that through. To put more light on my case i have added sample of my code. Thanks for help.

    main.cpp:
    Qt Code:
    1. #include <QApplication>
    2. #include <QGraphicsScene>
    3. #include <QGraphicsView>
    4. #include "square.h"
    5. #include "background.h"
    6.  
    7. int main(int argc, char *argv[])
    8. {
    9. QApplication a(argc, argv);
    10.  
    11. // create a scene
    12. QGraphicsScene * scene = new QGraphicsScene(0,0,200,250);
    13.  
    14.  
    15. Background * background = new Background();
    16. background->fillBackgroundWithSquares(scene);
    17.  
    18.  
    19.  
    20. // add a view
    21. QGraphicsView * view = new QGraphicsView(scene);
    22.  
    23. view->show();
    24.  
    25.  
    26. return a.exec();
    27. }
    To copy to clipboard, switch view to plain text mode 

    background.h:
    Qt Code:
    1. #ifndef BACKGROUND_H
    2. #define BACKGROUND_H
    3. #include <QGraphicsScene>
    4. #include <square.h>
    5. class Background
    6. {
    7. public:
    8. Background();
    9. void fillBackgroundWithSquares(QGraphicsScene *scene);
    10.  
    11. };
    12.  
    13. #endif // BACKGROUND_H
    To copy to clipboard, switch view to plain text mode 

    background.cpp:
    Qt Code:
    1. #include "background.h"
    2.  
    3. Background::Background()
    4. {
    5.  
    6. }
    7.  
    8. void Background::fillBackgroundWithSquares(QGraphicsScene *scene)
    9. {
    10. // create an item to put into the scene
    11. Square *squares[20][25];
    12.  
    13.  
    14. // add squares to the scene
    15. for (int i = 0; i < 20; i++)
    16. for (int j = 0; j < 25; j++) {
    17. squares[i][j] = new Square(i*10,j*10);
    18. scene->addItem(squares[i][j]);
    19. }
    20.  
    21. }
    To copy to clipboard, switch view to plain text mode 
    square.h:

    Qt Code:
    1. #ifndef SQUARE_H
    2. #define SQUARE_H
    3. #include <QGraphicsRectItem>
    4. #include <QGraphicsView>
    5. #include <QDragEnterEvent>
    6.  
    7.  
    8. class Square : public QGraphicsRectItem
    9. {
    10. public:
    11. Square(int x, int y);
    12.  
    13. private:
    14. QPen pen;
    15.  
    16. protected:
    17. void mousePressEvent(QGraphicsSceneMouseEvent * event);
    18. void dragEnterEvent(QGraphicsSceneDragDropEvent * event);
    19. void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
    20.  
    21. };
    22.  
    23. #endif // SQUARE_H
    To copy to clipboard, switch view to plain text mode 

    square.cpp:
    Qt Code:
    1. #include "square.h"
    2.  
    3. Square::Square(int x, int y)
    4. {
    5. // draw a square
    6. setRect(x,y,10,10);
    7. pen.setBrush(Qt::NoBrush);
    8.  
    9. setPen(pen);
    10.  
    11. setBrush(Qt::cyan);
    12. setAcceptDrops(true);
    13. setAcceptHoverEvents(true);
    14. }
    15.  
    16. // following functions are just attempt to make every square to be painted on black if I press my mouse button and move cursor over squares but none of the following work as I want.
    17.  
    18. void Square::mousePressEvent(QGraphicsSceneMouseEvent *event)
    19. {
    20. setBrush(Qt::black);
    21. }
    22.  
    23. void Square::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
    24.  
    25. {
    26. setBrush(Qt::black);
    27. }
    28.  
    29. void Square::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    30. {
    31. setBrush(Qt::black);
    32. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,796
    Thanks
    216
    Thanked 588 Times in 578 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Color rectangles using QGraphicsRectItem

    Try calling QGraphicsItem::update() after you set the new brush.

    I would also insert code that checks the current brush color -before- you call setBrush(), especially in the mouseMoveEvent(). You don't want to set the same color over and over again (and redraw over and over again with every tiny movement) if the color is already the one you want:

    Qt Code:
    1. if ( brush().color() != Qt::black )
    2. {
    3. setBrush( Qt::black );
    4. update();
    5. }
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color rectangles using QGraphicsRectItem

    Thank you for your answer d_stranz I've made some improvements as you suggest but still my problem has'nt been solved yet. Can you please give me a hint how to make every square color to black as i move mouse over squares with mouse button pressed ?

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,796
    Thanks
    216
    Thanked 588 Times in 578 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Color rectangles using QGraphicsRectItem

    i move mouse over squares with mouse button pressed
    If you read the documentation for QGraphicsItem::mousePressEvent() you will learn that once you press the mouse on an item, it grabs the mouse. This means that whether you move the mouse off of that item and onto another item, the original item receives the mouse events until you release the button. The way around this is to call QEvent::ignore() in your handler, but then that results in the mouse press being ignored until you release and press it again.

    If you call ignore() and then move to a different square with the mouse button still pressed, I do not know if this will result in a new mouse press event for the new item. If it does not, then basically you cannot accomplish what you want.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color rectangles using QGraphicsRectItem

    I've got stupid question, how to call ignore() ? Because if I do something like this:

    Qt Code:
    1. void Square::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. if ( brush().color() != Qt::black ){
    4. setBrush( Qt::black );
    5. update();
    6.  
    7. }
    8. event->ignore();
    9. }
    To copy to clipboard, switch view to plain text mode 

    then application throws an error: invalid use of incomplete type 'class QGraphicsSceneMouseEvent'

    so if i change event type to QEvent like that:

    Qt Code:
    1. void Square::mouseMoveEvent(QEvent *event)
    2. {
    3. if ( brush().color() != Qt::black ){
    4. setBrush( Qt::black );
    5. update();
    6.  
    7. }
    8. event->ignore();
    9. }
    To copy to clipboard, switch view to plain text mode 

    Application run properly but mouseMoveEvent handler will never be handled.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,796
    Thanks
    216
    Thanked 588 Times in 578 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Color rectangles using QGraphicsRectItem

    invalid use of incomplete type 'class QGraphicsSceneMouseEvent'
    Learn to understand what your compiler is telling you. This message means you have forgotten to #include the header file that defines QGraphicsSceneMouseEvent at the top of your cpp file.

    Application run properly but mouseMoveEvent handler will never be handled.
    Because by changing the signature for mouseMoveEvent() you have defined a new method for your Square class that Qt's event system knows nothing about and will never call. You should also understand that in C++, the combination of method name, return value type, and argument types define a function, not just the method name. You can't just arbitrarily replace one argument type for another. Those are different functions as far as the compiler, linker, and runtime are concerned, and the new one does not substitute for the old one. The old one still exists in Square's base class, and that's the one being called.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. The following user says thank you to d_stranz for this useful post:

    poor_fool_mloo (12th January 2018)

  8. #7
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color rectangles using QGraphicsRectItem

    Thank You for the expenation d_stranz. I will leave this thread open maybe someone will have an idea how to solve that.

  9. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,796
    Thanks
    216
    Thanked 588 Times in 578 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Color rectangles using QGraphicsRectItem

    maybe someone will have an idea how to solve that.
    How to solve what? The "incomplete type" error? I told you how to solve it - in your cpp file, you need to #include the header file where QGraphicsSceneMouseEvent is defined.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  10. #9
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color rectangles using QGraphicsRectItem

    Sorry for my impreciseness. By writting that maybe someone will have an idea how to solve that I meant that maybe someone will have an idea how to make every square color to black as i move mouse over squares with mouse button pressed. Adding #include <QGraphicsSceneMouseEvent> as You suggested was good answer to my ignore() error problem, thank You. But adding ignore() as above did'nt solved that problem with coloring squares.

  11. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,796
    Thanks
    216
    Thanked 588 Times in 578 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Color rectangles using QGraphicsRectItem

    did'nt solved that problem with coloring squares.
    No, it will not solve that problem. As I said, when you press the mouse button when the mouse is over a graphics item, that item will grab all of the mouse events until you release the button, no matter where the mouse moves to. This is to support click and drag so graphics items can be moved in a scene.

    Unless you rewrite the way the Qt graphics / view architecture processes mouse events, you can't change this behavior. It is not possible to implement something where you can press the mouse button on an item, keep it pressed, and have other items respond to the mouse. The item you pressed the mouse on owns the mouse until you release the button.

    I suggest you look for a different way to implement the behavior you want. One way could be to combine the mouse movement with a keyboard modifier (like Shift or Ctrl). If you get a hover enter event and the Shift key is pressed, then you can change the color of the square, for example.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  12. The following user says thank you to d_stranz for this useful post:

    poor_fool_mloo (12th January 2018)

  13. #11
    Join Date
    Jan 2018
    Posts
    6
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color rectangles using QGraphicsRectItem

    Thank You for your explanation and the advice d_stranz! The combination of hoverEnterEvent() and keyboard modifier really worked for me. Problem solved

  14. The following user says thank you to poor_fool_mloo for this useful post:

    d_stranz (12th January 2018)

Similar Threads

  1. How to draw two rectangles with QtQuick?
    By TheIndependentAquarius in forum Qt Quick
    Replies: 6
    Last Post: 27th September 2013, 11:32
  2. Drawing rectangles in QT
    By andreahmed in forum Qt Programming
    Replies: 5
    Last Post: 26th February 2012, 19:08
  3. Replies: 1
    Last Post: 9th August 2010, 19:44
  4. How to get QGraphicsRectItem filled color
    By wisconxing in forum Qt Programming
    Replies: 1
    Last Post: 3rd February 2009, 02:28
  5. editable rectangles
    By parmar ranjit in forum Qt Programming
    Replies: 3
    Last Post: 20th February 2008, 09:59

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.