Results 1 to 5 of 5

Thread: Drawing polygon using event filter in Qt

  1. #1
    Join Date
    Jun 2014
    Posts
    16
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows

    Default Drawing polygon using event filter in Qt

    I am working on a feature in my GUI that allow user to draw polygon by clicking the points.
    First the user needs to enable this function by clicking a button. After that the user clicks any four points on the screen. When the fourth point is clicked, all the 4 points will be connected to form a polygon.

    However the polygon is not appearing after the fourth is clicked. Instead there is a message of "QPainter::begin: Paint device returned engine == 0, type: 1". What is the problem in my code?

    Qt Code:
    1. bool QTGraphicsShape::eventFilter(QObject *obj, QEvent *event)
    2. {
    3. double static x[4],y[4];
    4. int static i;
    5. if ((event->type() == QEvent::GraphicsSceneMouseRelease) && (Draw3Points == true)) {
    6. QGraphicsSceneMouseEvent *mouseEvent = static_cast< QGraphicsSceneMouseEvent* >( event );
    7. QPointF img_coord_pt = mouseEvent->scenePos();
    8. x[i] = img_coord_pt.x();
    9. y[i] = img_coord_pt.y();
    10. i++;
    11. if (i >= 4)
    12. {
    13. Draw3Points = false;
    14. i=0;
    15. static const QPointF points[4] = {
    16. QPointF(x[0], y[0]),
    17. QPointF(x[1], y[1]),
    18. QPointF(x[2], y[2]),
    19. QPointF(x[3], y[3])
    20. };
    21. QPainter painter(this);
    22. painter.drawPolygon(points, 4);
    23. }
    24. return true;
    25. } else {
    26. return QObject::eventFilter(obj, event);
    27. }
    28. }
    29.  
    30. void QTGraphicsShape::on_pushButton_clicked()
    31. {
    32. ui.graphicsView->setMouseTracking(true);
    33. Draw3Points = true;
    34. m_pGraphicsScene->installEventFilter(this);
    35. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Drawing polygon using event filter in Qt

    You are drawing on "this". Is "this" an object of a class that is a QPaintDevice?

    Any specific reason for the event filter hack instead of implementing the event handling in the scene?

    Cheers,
    _

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,014
    Thanks
    280
    Thanked 816 Times in 805 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Drawing polygon using event filter in Qt

    In addition, you cannot use a QPainter to draw on screen anywhere except in a paintEvent(). See the docs:

    Warning: When the paintdevice is a widget, QPainter can only be used inside a paintEvent() function or in a function called by paintEvent().
    so, you need to collect the points in a data structure as the user clicks, and then draw the polygon in a paintEvent().

    Of course, you understand that with the code you are trying to implement (ie using a single static data structure to hold the points and the count of clicks), even if you move it into a paintEvent(), the QPainter will very briefly draw the polygon after the 4th click, then immediately erase it on the next paint event because you've set i = 0 and Draw3Points = false.

    You need to rethink what you really want your software to do and implement a set of data structures and logic that does it.
    Last edited by d_stranz; 17th September 2014 at 18:16.

  4. #4
    Join Date
    Jun 2014
    Posts
    16
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Drawing polygon using event filter in Qt

    Quote Originally Posted by anda_skoa View Post
    You are drawing on "this". Is "this" an object of a class that is a QPaintDevice?

    Any specific reason for the event filter hack instead of implementing the event handling in the scene?

    Cheers,
    _
    "this" is "class QTGraphicsShape : public QMainWindow"

    The reason I use event filter is that my drawing feature is only activated when I click certain button. Is it unnecessary in this case?

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Drawing polygon using event filter in Qt

    Quote Originally Posted by benz6699 View Post
    "this" is "class QTGraphicsShape : public QMainWindow"
    You can only draw on a QWidget in its paintEvent() method.
    You can of course draw into a buffer elsewhere and then draw the buffer in paintEvent().

    In the case of QMainWindow it is very uncommon to do any drawing there, usually it contains further widgets as its content.

    Quote Originally Posted by benz6699 View Post
    The reason I use event filter is that my drawing feature is only activated when I click certain button. Is it unnecessary in this case?
    That is not related at all.

    Mouse event processing should happen at the widget that receives them, or in the case of a QGraphicsView potentially in the scene or its items.

    Cheers,
    _

Similar Threads

  1. Replies: 2
    Last Post: 12th May 2012, 11:30
  2. Event filter question
    By d_stranz in forum Qt Programming
    Replies: 7
    Last Post: 7th July 2011, 23:08
  3. Strange whiskers when drawing a polygon
    By feraudyh in forum Newbie
    Replies: 0
    Last Post: 22nd November 2009, 16:20
  4. Replies: 3
    Last Post: 3rd March 2009, 12:24
  5. Optimizing polygon clipping in QGraphicsScene drawing
    By maverick_pol in forum Qt Programming
    Replies: 1
    Last Post: 28th September 2008, 20:41

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.