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. Mouse interaction issues after adding items into the QGraphicsScene
Forum Updated to NodeBB v4.3 + New Features

Mouse interaction issues after adding items into the QGraphicsScene

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 1.4k Views 3 Watching
  • 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.
  • M Offline
    M Offline
    MShao
    wrote on last edited by
    #1
    1. I've set the item to setAcceptedMouseButtons(0) but it still shows up in mousePress() function.
    2. In order to select a QGraphicsEllipseItem, I need to click on the tiny left top corner of the oval shape. I override shape() for QGraphicsEllipseItem and still can't get the area clickable to return in mousePress().

    BTW, I'm new in Qt, and thank you for helping.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      Please show some code, and we may be able to help.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        MShao
        wrote on last edited by
        #3
        1. Here is how I setAccceptedMouseButton(0):
          ...
          lRect = dScene->addRect(lLeftX, lTopY, lRightX-lLeftX, lFontHeight, lPen, QBrush(*lColor));
          lRect->setFlag(QGraphicsItem::ItemIgnoresTransformations);
          lRect->setAcceptedMouseButtons(0);
          ....

        And in the class that inherited from QGraphicsView:
        void myViewCls::mousePressEvent(QMouseEvent* xEvent)
        {
        qDebug() << "myViewCls::mousePressEvent, Pos? " << xEvent->pos();
        QPointF lPoint = mapToScene(xEvent->pos());
        qDebug() << "myViewCls::mousePressEvent, Scene Pos? " << lPoint;
        QGraphicsItem* lItem = dScene->itemAt(lPoint, transform());
        qDebug() << "Item Pressed? " << lItem;
        if (lItem!= NULL)
        qDebug() << "Found item type? " << lItem->type();

        QGraphicsView::mousePressEvent(xEvent);
        

        }

        And the qDebug() just keep showing the lRect info when I click on that region.

        1. This is the shape() I overwrite:
          QPainterPath QGraphicsEllipseItem::shape() const
          {
          QPainterPath lPath;
          QRectF lRect = rect();
          QPolygon lPg;
          lPg << QPoint(rect().top(), rect().left());
          lPg << QPoint(rect().top(), rect().right());
          lPg << QPoint(rect().bottom(), rect().right());
          lPg << QPoint(rect().bottom(), rect().left());
          lPath.addPolygon(lPg);
          return lPath;
          }

        But the mousePressEvent only takes the very top and very left point to recognize the oval I drew. I thought by default the width and height should be included too, but even after I overwrite the shape, it doesn't work. Is it because of the itemAt restriction?

        Thank you for any help anyone can provide! I"m stuck!

        -Michelle

        K 1 Reply Last reply
        0
        • M MShao
          1. Here is how I setAccceptedMouseButton(0):
            ...
            lRect = dScene->addRect(lLeftX, lTopY, lRightX-lLeftX, lFontHeight, lPen, QBrush(*lColor));
            lRect->setFlag(QGraphicsItem::ItemIgnoresTransformations);
            lRect->setAcceptedMouseButtons(0);
            ....

          And in the class that inherited from QGraphicsView:
          void myViewCls::mousePressEvent(QMouseEvent* xEvent)
          {
          qDebug() << "myViewCls::mousePressEvent, Pos? " << xEvent->pos();
          QPointF lPoint = mapToScene(xEvent->pos());
          qDebug() << "myViewCls::mousePressEvent, Scene Pos? " << lPoint;
          QGraphicsItem* lItem = dScene->itemAt(lPoint, transform());
          qDebug() << "Item Pressed? " << lItem;
          if (lItem!= NULL)
          qDebug() << "Found item type? " << lItem->type();

          QGraphicsView::mousePressEvent(xEvent);
          

          }

          And the qDebug() just keep showing the lRect info when I click on that region.

          1. This is the shape() I overwrite:
            QPainterPath QGraphicsEllipseItem::shape() const
            {
            QPainterPath lPath;
            QRectF lRect = rect();
            QPolygon lPg;
            lPg << QPoint(rect().top(), rect().left());
            lPg << QPoint(rect().top(), rect().right());
            lPg << QPoint(rect().bottom(), rect().right());
            lPg << QPoint(rect().bottom(), rect().left());
            lPath.addPolygon(lPg);
            return lPath;
            }

          But the mousePressEvent only takes the very top and very left point to recognize the oval I drew. I thought by default the width and height should be included too, but even after I overwrite the shape, it doesn't work. Is it because of the itemAt restriction?

          Thank you for any help anyone can provide! I"m stuck!

          -Michelle

          K Offline
          K Offline
          kenchan
          wrote on last edited by kenchan
          #4

          @MShao
          Help me understand what you are doing exactly. So you have not created a QGraphicsEllipseItem of your own, with something like

          class MyEllipseItem : public QGraphicsEllipseItem
          {
           .... your stuff
          };
          

          You are just overriding the QGraphicsEllipseItem functions directly?

          1 Reply Last reply
          0
          • M Offline
            M Offline
            MShao
            wrote on last edited by MShao
            #5

            No, I don't have my own class, because I don't have my own stuff to do. All I'm doing is drawing the oval, and then I need to click it to get it's data in order to do something.
            Or have the tooltip for it. I just tried the tooltip and it's not working either. I'm sure there is something I should be setting that I didn't.
            A basic question, if I'm draing an Ellipse with the x, y and height and width, why is the boundingRect not having this area as default? Why do we need to always overwrite boundingRect?

            Thank you.

            K 1 Reply Last reply
            0
            • M MShao

              No, I don't have my own class, because I don't have my own stuff to do. All I'm doing is drawing the oval, and then I need to click it to get it's data in order to do something.
              Or have the tooltip for it. I just tried the tooltip and it's not working either. I'm sure there is something I should be setting that I didn't.
              A basic question, if I'm draing an Ellipse with the x, y and height and width, why is the boundingRect not having this area as default? Why do we need to always overwrite boundingRect?

              Thank you.

              K Offline
              K Offline
              kenchan
              wrote on last edited by kenchan
              #6

              @MShao
              Yes you do. I think you will make things easier for yourself if you subclass your graphics ellipse the way that is recommended in the docs. Especially if you need to overwrite the shape and paint functions. It is an easy thing to do and your item will begin to behave the way that all items are supposed to.
              I am sure you have seen the docs about how to do it here.
              There is code for a simple example of a subclassed QGraphicsItem i have posted previously here.
              It is a different shape from yours but you might find it useful.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                MShao
                wrote on last edited by MShao
                #7

                Hi @kenchan
                Thank you for your help. Question, why do we have our own "paint"? In the example of the doc:

                void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                QWidget *widget)
                {
                painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);
                }

                Why do we call QPainter->drawRoundRect()? Shouldn't we just call QGraphicsScene->addEllipse() directly?

                Now I'm confused about when to use QPainter->drawXXX() and when to use QGraphicsScene->addXXXX().

                Thank you again for your explanation, Ken.

                K 1 Reply Last reply
                0
                • M MShao

                  Hi @kenchan
                  Thank you for your help. Question, why do we have our own "paint"? In the example of the doc:

                  void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                  QWidget *widget)
                  {
                  painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);
                  }

                  Why do we call QPainter->drawRoundRect()? Shouldn't we just call QGraphicsScene->addEllipse() directly?

                  Now I'm confused about when to use QPainter->drawXXX() and when to use QGraphicsScene->addXXXX().

                  Thank you again for your explanation, Ken.

                  K Offline
                  K Offline
                  kenchan
                  wrote on last edited by kenchan
                  #8

                  @MShao
                  The example is just an example of the minimum subclass you can do with a QGraphicsItem. It shows that you can use the painter to draw anything you want. All graphics items call the QPainter to paint themselves. The example is drawing a shape that you can't draw with a standard QGraphicsItem, one which has round corners.
                  If you were to call QGraphicsScene->addXXX from inside your own graphics item you would have to keep track of it and manage it. It is far easier and natural to do all your own paint shape and bounding box management for your own class directly. You can create very intelligent objects that way if you need to.
                  If you don't need all that don't subclass a QGraphicsItem I suggest you just use the standard items and manipulate them using the standard functions.

                  You probably would not actually subclass the QGraphicsEllipseItem anyway, just the QGraphicsItem class.

                  class MyEllipseItem  : public QGraphicsItem
                  {
                  ... my stuff
                  };
                  

                  Just to be clear, if you just want to use the standard QGraphicsItems you don't need to implement paint or bounding box etc. for them. In fact you can't do that if you don't overwrite them like that because those functions belong the QGraphicsItem class.

                  M 1 Reply Last reply
                  0
                  • K kenchan

                    @MShao
                    The example is just an example of the minimum subclass you can do with a QGraphicsItem. It shows that you can use the painter to draw anything you want. All graphics items call the QPainter to paint themselves. The example is drawing a shape that you can't draw with a standard QGraphicsItem, one which has round corners.
                    If you were to call QGraphicsScene->addXXX from inside your own graphics item you would have to keep track of it and manage it. It is far easier and natural to do all your own paint shape and bounding box management for your own class directly. You can create very intelligent objects that way if you need to.
                    If you don't need all that don't subclass a QGraphicsItem I suggest you just use the standard items and manipulate them using the standard functions.

                    You probably would not actually subclass the QGraphicsEllipseItem anyway, just the QGraphicsItem class.

                    class MyEllipseItem  : public QGraphicsItem
                    {
                    ... my stuff
                    };
                    

                    Just to be clear, if you just want to use the standard QGraphicsItems you don't need to implement paint or bounding box etc. for them. In fact you can't do that if you don't overwrite them like that because those functions belong the QGraphicsItem class.

                    M Offline
                    M Offline
                    MShao
                    wrote on last edited by
                    #9

                    @kenchan

                    Thank you for the explanation. I will try to do the subclass and see how it goes. Now I'm having some hope. Hope it doesn't get crushed. :)

                    Thanks again!
                    -Michelle

                    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