Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Dots while freehand drawing on QGraphicsView and Problem while remove items from QGraphicsView.

Dots while freehand drawing on QGraphicsView and Problem while remove items from QGraphicsView.

Scheduled Pinned Locked Moved General and Desktop
20 Posts 2 Posters 8.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Himanshu Rohilla
    wrote on last edited by
    #1

    Hi,

    I want to draw freehand drawing on QGraphicsView. I am able to draw it. But, when the line draw on QGraphicsView, it also create small small dots. How can i remove these dots ? I am sharing code of mouse press, mouse move and mouse release on QGraphicsView and line draw function where i am adding the line on QGraphicsScene which is associated with QGraphicsView.
    The following code also contains code for Eraser. Eraser is also works but it also remove items which are out of Eraser's area.

    @void WhiteBoardView::mousePressEvent (QMouseEvent *event)
    {
    if(event->button() == Qt::LeftButton)
    {
    vbMousePressed = true;

        if(vbPenSelected)
        {
            /* This code will execute when Pen is selected */
    
            currntPt = previousPt = mapToScene(event->pos());      
            drawLineTo(previousPt,currntPt,vPenForDrawing);
        }
        else if(vbEraserSelected)
        {
            /* This code will execute when Eraser is selected */
    
            rad = vRadiusForEarser;
            pt = mapToScene(event->pos());
    
            EraserLineTo(pt, rad);
        }
    
    
    }
    

    }

    void WhiteBoardView::mouseMoveEvent (QMouseEvent *event)
    {
    vbMouseMoving = true;

    if(vbMousePressed && vbMouseMoving)
    {
        if(vbPenSelected)
        {
            /* This code will execute when Pen is selected */
    
            previousPt = currntPt;
            currntPt = mapToScene(event->pos());
            drawLineTo(previousPt,currntPt,vPenForDrawing);
        }
        else if(vbEraserSelected)
        {
            /* This code will execute when Eraser is selected */
    
            rad = vRadiusForEarser;
            pt = mapToScene(event->pos());
    
            EraserLineTo(pt, rad);
    
        }
    
    }
    

    }

    void WhiteBoardView::mouseReleaseEvent (QMouseEvent *event)
    {
    Q_UNUSED(event);

    if(vbMouseMoving)
    {
        if(vbPenSelected)
        {
    
        }
    
        else if(vbEraserSelected)
        {
            /* Following code is used to remove items from QGraphicsScene  */
    
            mWhiteBoardScene->addEllipse(pt.x()-rad, pt.y()-rad, rad*2.0, rad*2.0,QPen(Qt::blue), QBrush(Qt::transparent));
            listOfItems = mWhiteBoardScene->items(pt.x()-rad, pt.y()-rad, rad*2.0, rad*2.0, Qt::IntersectsItemShape);
    
            for(int i=0; i < listOfItems.size(); i++)
            {
                mWhiteBoardScene->removeItem(listOfItems[i], true);
                delete listOfItems[i];
            }
    
    
            listOfItems.clear();
        }
    
        vbMouseMoving = false;
        vbMousePressed = false;
    }
    

    }

    /* Following function is used to draw line on QGraphicsScene */

    void WhiteBoardView::drawLineTo(const QPointF &previous, const QPointF &current, const QPen& drawPen)
    {
    mWhiteBoardScene->addLine(previous.x(), previous.y(), current.x(), current.y(), drawPen);
    }

    /* Following function is used to Remove Items from QGraphicsScene */

    void WhiteBoardView::EraserLineTo(const QPointF &current, double radius)
    {

    listOfItems = mWhiteBoardScene->items(current.x()-radius, current.y()-radius, radius*2.0, radius*2.0, Qt::IntersectsItemShape);
    
    for(int i=0; i < listOfItems.size(); i++)
    {
        mWhiteBoardScene->removeItem(listOfItems[i], true);
        delete listOfItems[i];
    }
    
    mWhiteBoardScene->addEllipse(current.x()-radius, current.y()-radius, radius*2.0, radius*2.0,QPen(Qt::blue), QBrush(Qt::transparent));
    

    }@

    Thanks in advance ...

    HImanshu Rohilla

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      i think your dots appear because of pixelation.
      Try to set render hint:
      @
      view->setRenderHint( QPainter::Antialiasing );
      @

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • H Offline
        H Offline
        Himanshu Rohilla
        wrote on last edited by
        #3

        I already set this render hint.

        HImanshu Rohilla

        1 Reply Last reply
        0
        • raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          ok to the drawLineTo() method add the following debug message and check if alwys correct lines are drawn:
          @
          qDebug() << Q_FUNC_INFO << previous << current;
          @

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            i just compiled and ran the code you posted and i don't get the dots you mentioned. Could you please upload a screenshot showing the issue?

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • H Offline
              H Offline
              Himanshu Rohilla
              wrote on last edited by
              #6

              Hi Raven,

              You can find screenshot from the below link.

              !http://http://www.freeimagehosting.net/govdu()!

              This is screenshot of my drawing. You can see small small dots.

              HImanshu Rohilla

              1 Reply Last reply
              0
              • H Offline
                H Offline
                Himanshu Rohilla
                wrote on last edited by
                #7

                http://www.freeimagehosting.net/govdu

                From the above mentioned link , you can see screenshot.

                Thanks in advance.

                HImanshu Rohilla

                1 Reply Last reply
                0
                • raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  ok now i know what you mean.... this issue comes from a non-opaque pen/brush color. So that the endings of the lines overlap...

                  You have 2 possibilities now:

                  1. sub class a QGraphicsItem and do the painting yourself. On every move event you add the current position to the item and in the item's paint event you draw it's points with QPainter::drawPolyline()

                  2. instead of adding multiple lines to the scene you add 1 "shape item":http://qt-project.org/doc/qt-4.8/qgraphicspathitem.html to the scene. in every move event you add a line to painter path object "merge it down":http://qt-project.org/doc/qt-4.8/qpainterpath.html#simplified and set i to the shape item.

                  I would suggest the 2nd method since it will be easier to implement your eraser with just "removing the eraser shape":http://qt-project.org/doc/qt-4.8/qpainterpath.html#subtracted from the current path in every move event.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  0
                  • raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    so a possible solution to 2) could be as simple as:
                    @
                    WhiteBoardView::WhiteBoardView()
                    {
                    mDrawnPathItem = mWhiteBoardScene->addPath(QPainterPath());
                    mDrawnPathItem->setBrush( QColor(...) );
                    mDrawnPathItem->setPen(Qt::NoPen);
                    }

                    void WhiteBoardView::drawLineTo(const QPointF &previous, const QPointF &current, const QPen& drawPen)
                    {
                    QGraphicsLineItem lineHelper;
                    lineHelper.setLine( QLineF(previous, current) );
                    lineHelper.setPen(drawPen);

                    QPainterPath path = mDrawnPathItem->path();
                        path.setFillRule(Qt::WindingFill);
                        path.addPath( lineHelper.shape() );
                    path = path.simplified();
                    
                    mDrawnPathItem->setPath(path);    //mDrawnPathItem is of type QGraphicsPathItem* and was added in the constructor with an empty QPainterPath()
                    

                    }
                    @

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    0
                    • H Offline
                      H Offline
                      Himanshu Rohilla
                      wrote on last edited by
                      #10

                      Thanks a lot Raven.

                      It works very fine. But, I have one more problem with this. If i draw a line with a color (for example: Black) , it draws very fine. But, when i start drawing again with different color(for example: Red) , it also changes the color of drawn lines( Black to Red)...

                      Once again, thanks a lot....

                      HImanshu Rohilla

                      1 Reply Last reply
                      0
                      • raven-worxR Offline
                        raven-worxR Offline
                        raven-worx
                        Moderators
                        wrote on last edited by
                        #11

                        yes sure... solution to your problem was to not create multiple line-items but one single item so get rid of the overlapping edges (dots in your case). Thus a change of color affects the whole item.
                        If you need to draw multi color lines, then you need to create for every color a own path.

                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                        If you have a question please use the forum so others can benefit from the solution in the future

                        1 Reply Last reply
                        0
                        • H Offline
                          H Offline
                          Himanshu Rohilla
                          wrote on last edited by
                          #12

                          Thanks Raven.. Now, i am using different different path for every color. It works very fine.

                          But, i could not understand what you want to say about Eraser concept, sorry.. :(

                          HImanshu Rohilla

                          1 Reply Last reply
                          0
                          • raven-worxR Offline
                            raven-worxR Offline
                            raven-worx
                            Moderators
                            wrote on last edited by
                            #13

                            when in "eraser-mode" (in the mouse move event) you create a QPainterPath with the radius and the center of the current mouse position. Now just "subtract":http://qt-project.org/doc/qt-4.8/qpainterpath.html#subtracted the eraser painterpath from every item you have in your graphicsview.
                            Thats it.

                            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                            If you have a question please use the forum so others can benefit from the solution in the future

                            1 Reply Last reply
                            0
                            • H Offline
                              H Offline
                              Himanshu Rohilla
                              wrote on last edited by
                              #14

                              I try this but not working.... :(

                              the following is my code.

                              @WhiteBoardView::WhiteBoardView()
                              {
                              /* This is for Red Color */
                              mRedPathItem = mWhiteBoardScene->addPath(QPainterPath());
                              mRedPathItem->setPen(Qt::NoPen);

                               /*  This is for Green Color */
                               mGreenPathItem = mWhiteBoardScene->addPath(QPainterPath());
                               mGreenPathItem->setPen(Qt::NoPen);
                               
                               /*  This is for Blue Color */
                               mBluePathItem = mWhiteBoardScene->addPath(QPainterPath());
                               mBluePathItem->setPen(Qt::NoPen);
                              
                               /*  This is for Eraser */
                               mEraserPathItem = mWhiteBoardScene->addPath(QPainterPath());
                               mEraserPathItem->setPen(Qt::NoPen);
                              

                              }

                              /* When in "Eraser Mode(In mouseMoveEvent)", i am calling the following function. */

                              void WhiteBoardView::eraseLineTo(const QPointF &current)
                              {
                              QPainterPath eraserPath = mEraserPathItem->path();

                              eraserPath.addEllipse(current, 20,20);
                              
                              QList<QGraphicsItem*> items = this->items();
                              
                              for(int i=0; i<items.size(); i++)
                              {
                                  QPainterPath drawnPath = items[i]->shape();
                              
                                  drawnPath.subtracted(eraserPath);
                              }
                              

                              }@

                              HImanshu Rohilla

                              1 Reply Last reply
                              0
                              • raven-worxR Offline
                                raven-worxR Offline
                                raven-worx
                                Moderators
                                wrote on last edited by
                                #15

                                you need to save the changes back to the item, since you only get a copy of the shape from the item. And also you don't need to add an eraser-item to the scene and add a circle to it on every call ;)
                                @
                                void WhiteBoardView::eraseLineTo(const QPointF &current)
                                {
                                QPainterPath eraserPath;
                                eraserPath.addEllipse(current, 20,20);

                                QList<QGraphicsItem*> items = this->items();
                                
                                for(int i=0; i<items.size(); i++)
                                {
                                    QPainterPath drawnPath = items[i]->shape();
                                    drawnPath.subtracted(eraserPath);
                                    items[i]->setShape(drawnPath);
                                }
                                

                                }
                                @

                                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                If you have a question please use the forum so others can benefit from the solution in the future

                                1 Reply Last reply
                                0
                                • H Offline
                                  H Offline
                                  Himanshu Rohilla
                                  wrote on last edited by
                                  #16

                                  items[i] which is a QGraphicsItem does not have any "setShape" property. I also create a new instance of QGraphicsPathItem and using that i again set the path. But, it also does not work.

                                  @void WhiteBoardView::EraserLineTo(const QPointF &current, double radius)
                                  {
                                  QPainterPath eraserPath = mEraserPathItem->path();
                                  eraserPath.addEllipse(current, 20,20);

                                  QList<QGraphicsItem*> items = this->items();
                                  
                                  for(int i=0; i<items.size(); i++)
                                  {
                                      QPainterPath drawnPath = items[i]->shape();
                                  
                                      QGraphicsPathItem *pathItem = new QGraphicsPathItem();
                                  
                                      pathItem->setPath(drawnPath.subtracted(eraserPath));
                                  }
                                  

                                  }@

                                  HImanshu Rohilla

                                  1 Reply Last reply
                                  0
                                  • raven-worxR Offline
                                    raven-worxR Offline
                                    raven-worx
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    sorry...the path property is the right one.

                                    In your code you create a new QGraphicsPathItem but never add it to the scene. And even if you would add it to the scene you would leave the old items in there.
                                    Why not holding your own list of the added QGraphicsPathItem objects?
                                    @
                                    void WhiteBoardView::EraserLineTo(const QPointF &current, double radius)
                                    {
                                    QPainterPath eraserPath = mEraserPathItem->path();
                                    eraserPath.addEllipse(current, 20,20);

                                        //m_DrawnItems = QList<QGraphicsPathItem*>
                                        foreach( QGraphicsPathItem* item, m_DrawnItems)
                                        {
                                            QPainterPath drawnPath = item->path();
                                                  drawnPath.subtracted(eraserPath)
                                            item->setPath(drawnPath);
                                        }
                                    }
                                    

                                    @
                                    so every time you add a linepath to the scene you need to also add it to the m_DrawnItems list

                                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                    If you have a question please use the forum so others can benefit from the solution in the future

                                    1 Reply Last reply
                                    0
                                    • H Offline
                                      H Offline
                                      Himanshu Rohilla
                                      wrote on last edited by
                                      #18

                                      thanks sir....
                                      Now, everything is going fine... :)

                                      thanks a lot....

                                      HImanshu Rohilla

                                      1 Reply Last reply
                                      0
                                      • H Offline
                                        H Offline
                                        Himanshu Rohilla
                                        wrote on last edited by
                                        #19

                                        Hi Raven,

                                        As u told me about how to do drawing on QGraphicsView and how to remove drawn paths. Now, i am facing a new problem while removing drawn paths.

                                        If i draw large no. of polygons , then the number of paths will increase and the size of list which maintain all paths(m_DrawnItems) is large. In the following code, which is to remove paths from view, For loop is taking a lot of time in case of large number of path.

                                        @ void WhiteBoardView::EraserLineTo(const QPointF &current, double radius)
                                        {
                                        QPainterPath eraserPath = mEraserPathItem->path();
                                        eraserPath.addEllipse(current, 20,20);

                                            //m_DrawnItems = QList<QGraphicsPathItem*>
                                            foreach( QGraphicsPathItem* item, m_DrawnItems)
                                            {
                                                QPainterPath drawnPath = item->path();
                                                      drawnPath.subtracted(eraserPath)
                                                item->setPath(drawnPath);
                                            }
                                        }@
                                        

                                        Is there any way which removes the drawn paths fastly ???

                                        HImanshu Rohilla

                                        1 Reply Last reply
                                        0
                                        • H Offline
                                          H Offline
                                          Himanshu Rohilla
                                          wrote on last edited by
                                          #20

                                          Another problem is that i can't draw free hand drawing on images which are drawn on QGraphicsView .....

                                          HImanshu Rohilla

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved