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. highlight QGraphicsItem
Forum Updated to NodeBB v4.3 + New Features

highlight QGraphicsItem

Scheduled Pinned Locked Moved Solved General and Desktop
43 Posts 4 Posters 14.0k Views 4 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.
  • U user4592357

    @kenchan
    no this is what i get:

    no hover:
    alt text

    after hover:
    alt text

    code:

        def paint(self, painter, option, widget):
            pen = QPen(Qt.red)
            if self.__hovered:
                # what should go here?
                self.__hovered = False
                pen.setColor(Qt.white)
                pen.setWidth(8)
                painter.setPen(pen)
                painter.drawLine(QPoint(0, 0), QPoint(100, 100))
                painter.drawLine(QPoint(0, 100), QPoint(100, 0))
    
            pen.setWidth(4)
            painter.setPen(pen)
    
            line = QLine(QPoint(0, 0), QPoint(100, 100))
            painter.drawLine(line)
            painter.drawLine(QPoint(0, 100), QPoint(100, 0))
    
        def boundingRect(self):
            return QRectF(0, 0, 108, 108)
    
        def hoverEnterEvent(self, event):
            # self.setGraphicsEffect(QGraphicsColorizeEffect())
            self.__hovered = True
            self.update()
            self.prepareGeometryChange()
    
        def hoverLeaveEvent(self, event):
            self.setGraphicsEffect(None)
    
    K Offline
    K Offline
    kenchan
    wrote on last edited by
    #20

    @user4592357
    Hmm so that red thing is your thin line version?

    U 1 Reply Last reply
    0
    • K kenchan

      @user4592357
      Hmm so that red thing is your thin line version?

      U Offline
      U Offline
      user4592357
      wrote on last edited by
      #21

      @kenchan
      yes

      K 2 Replies Last reply
      0
      • U user4592357

        @kenchan
        yes

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

        @user4592357
        so, it is drawing it but in the wrong place?

        1 Reply Last reply
        0
        • U user4592357

          @kenchan
          yes

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

          @user4592357
          you are still not reseting the hover flag in hoverleave so it is always on, right?

          U 1 Reply Last reply
          0
          • K kenchan

            @user4592357
            you are still not reseting the hover flag in hoverleave so it is always on, right?

            U Offline
            U Offline
            user4592357
            wrote on last edited by
            #24

            @kenchan
            i reset it after drawing the white line.
            it is drawing above red line instead of around it

            K 1 Reply Last reply
            0
            • U user4592357

              @kenchan
              i reset it after drawing the white line.
              it is drawing above red line instead of around it

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

              @user4592357
              Well I am sorry to say that i just made a test using the same ideas in C++ and it works just fine for me and I don't have to call update :-).
              So are we seeing a Python issue here or is it your paint function ?

              U 1 Reply Last reply
              1
              • K kenchan

                @user4592357
                Well I am sorry to say that i just made a test using the same ideas in C++ and it works just fine for me and I don't have to call update :-).
                So are we seeing a Python issue here or is it your paint function ?

                U Offline
                U Offline
                user4592357
                wrote on last edited by user4592357
                #26

                @kenchan
                can you please share the code? maybe i am missing something?

                K 4 Replies Last reply
                0
                • U user4592357

                  @kenchan
                  can you please share the code? maybe i am missing something?

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

                  @user4592357
                  It is in an app for testing my QGraphicsItems but I can share the code for the subclass.
                  As a matter of interest what settings do you use for the QGraphicsScene and View? maybe the drawing is being influenced by those settings?

                  1 Reply Last reply
                  0
                  • U user4592357

                    @kenchan
                    can you please share the code? maybe i am missing something?

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

                    @user4592357
                    Looking at your paint code, I think it is wrong. I think you should separate the line drawing into two if sections.

                    One draws both lines when hovering and the other draws just one line when not. That is how my code is. I tried it your way and I only saw the the thick lines.

                    1 Reply Last reply
                    0
                    • U user4592357

                      @kenchan
                      can you please share the code? maybe i am missing something?

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

                      @user4592357

                      Here is my code, i hope it helps.

                      EDIT: added the code for the shape() member function;
                      Using a path stroker with the same line thickness as the thin line.
                      Also, made the highlight line 50% transparent.

                      The header

                      class TestItem : public QGraphicsItem
                      {
                      public:
                          bool hovering;
                      public:
                          explicit TestItem(QGraphicsItem * parent = 0);
                      
                          void setHovering(bool flag);
                          QRectF boundingRect() const;
                          void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                         QPainterPath shape() const;
                      
                          virtual void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
                          virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
                      
                      };
                      

                      The code

                      TestItem::TestItem(QGraphicsItem * parent) : QGraphicsItem(parent)
                      {
                          setAcceptHoverEvents(true);
                          hovering = false;
                      }
                      
                      void TestItem::setHovering(bool flag)
                      {
                          hovering = flag;
                      
                      }
                      
                      QRectF TestItem::boundingRect() const
                      {
                          if(hovering)
                              return QRectF(-4, -4, 106, 106);
                          else
                              return QRectF(-2,-2, 102, 102);
                      }
                      
                      void TestItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                      {
                          QPen pen1(QBrush(QColor(0,255,0,128)),8,Qt::SolidLine,Qt::RoundCap);
                          QPen pen2(QBrush(QColor(255,0,0)),2,Qt::SolidLine,Qt::RoundCap);
                      
                          if(hovering)
                          {
                              painter->setPen(pen1);
                              painter->drawLine(0.0,0.0,100.0,100.0);
                              painter->drawLine(0.0,100.0,100.0,00.0);
                      
                              painter->setPen(pen2);
                              painter->drawLine(0.0,0.0,100.0,100.0);
                              painter->drawLine(0.0,100.0,100.0,00.0);
                          }
                          else
                          {
                              painter->setPen(pen2);
                              painter->drawLine(0.0,0.0,100.0,100.0);
                              painter->drawLine(0.0,100.0,100.0,00.0);
                          }
                      }
                      
                      QPainterPath TestItem::shape() const
                      {
                          QPainterPath path;
                          path.moveTo(0,0);
                          path.lineTo(100,100);
                          path.moveTo(0,100);
                          path.lineTo(100,0);
                          QPen pen(QBrush(QColor(255,0,0)),2,Qt::SolidLine,Qt::RoundCap);
                          QPainterPathStroker stroker(pen);
                          return stroker.createStroke(path);
                      }
                      
                      void TestItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
                      {
                          prepareGeometryChange();
                          setHovering(true);
                      }
                      
                      void TestItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
                      {
                          prepareGeometryChange();
                          setHovering(false);
                      }
                      
                      1 Reply Last reply
                      3
                      • U user4592357

                        @kenchan
                        can you please share the code? maybe i am missing something?

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

                        @user4592357
                        I edited the code a bit to make it thicker gave it round caps and made the bounding rect a tad bigger. It was leaving crud behind after it was removed :-)
                        looks nicer now.

                        U 1 Reply Last reply
                        1
                        • K kenchan

                          @user4592357
                          I edited the code a bit to make it thicker gave it round caps and made the bounding rect a tad bigger. It was leaving crud behind after it was removed :-)
                          looks nicer now.

                          U Offline
                          U Offline
                          user4592357
                          wrote on last edited by user4592357
                          #31

                          @kenchan
                          thnaks.

                          i was missing the call to prepareGeometryChange() in hoverLeaveEvent

                          by the way i noticed that when i hover over the bottom (in picture) item, it "goes up". when i hover over the top item, it "goes down".

                          this happens only after first time hovering. after that they don't move.

                          what is the reason?

                          K 2 Replies Last reply
                          0
                          • U user4592357

                            @kenchan
                            thnaks.

                            i was missing the call to prepareGeometryChange() in hoverLeaveEvent

                            by the way i noticed that when i hover over the bottom (in picture) item, it "goes up". when i hover over the top item, it "goes down".

                            this happens only after first time hovering. after that they don't move.

                            what is the reason?

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

                            @user4592357
                            that is probably the scene or the view adjusting the scaling for the added items. That is why I asked about the settings you are applying to those before doing the drawing.

                            U 1 Reply Last reply
                            0
                            • U user4592357

                              @kenchan
                              thnaks.

                              i was missing the call to prepareGeometryChange() in hoverLeaveEvent

                              by the way i noticed that when i hover over the bottom (in picture) item, it "goes up". when i hover over the top item, it "goes down".

                              this happens only after first time hovering. after that they don't move.

                              what is the reason?

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

                              @user4592357
                              Please mark the thread as solved if that is the case.

                              1 Reply Last reply
                              0
                              • K kenchan

                                @user4592357
                                that is probably the scene or the view adjusting the scaling for the added items. That is why I asked about the settings you are applying to those before doing the drawing.

                                U Offline
                                U Offline
                                user4592357
                                wrote on last edited by user4592357
                                #34

                                @kenchan
                                the only setting i have is applied to the view:

                                setRenderHint(QPainter.Antialiasing)
                                setRenderHint(QPainter.TextAntialiasing)
                                

                                removing them doesn't solve the problem, however.

                                K 1 Reply Last reply
                                0
                                • U user4592357

                                  @kenchan
                                  the only setting i have is applied to the view:

                                  setRenderHint(QPainter.Antialiasing)
                                  setRenderHint(QPainter.TextAntialiasing)
                                  

                                  removing them doesn't solve the problem, however.

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

                                  @user4592357
                                  No they wouldn't, i was thinking more in terms of...

                                  setViewportUpdateMode()
                                  setResizeAnchor()
                                  setDragMode()
                                  setHorizontalScrollBarPolicy()
                                  setSceneRect()
                                  

                                  and the like on the QGraphicsView. These things can affect how the scene behaves. It is a good idea to check how they affect yours.

                                  U 1 Reply Last reply
                                  0
                                  • K kenchan

                                    @user4592357
                                    No they wouldn't, i was thinking more in terms of...

                                    setViewportUpdateMode()
                                    setResizeAnchor()
                                    setDragMode()
                                    setHorizontalScrollBarPolicy()
                                    setSceneRect()
                                    

                                    and the like on the QGraphicsView. These things can affect how the scene behaves. It is a good idea to check how they affect yours.

                                    U Offline
                                    U Offline
                                    user4592357
                                    wrote on last edited by
                                    #36

                                    @kenchan
                                    setSceneRect() seems to do the job. but how do i tell it to use all the available area as scene rect? because i might have dockable widgets enabled in which case i need the scene rect to be smaller (i hope i could explain it)

                                    K 1 Reply Last reply
                                    0
                                    • U user4592357

                                      @kenchan
                                      setSceneRect() seems to do the job. but how do i tell it to use all the available area as scene rect? because i might have dockable widgets enabled in which case i need the scene rect to be smaller (i hope i could explain it)

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

                                      @user4592357
                                      Yes well that is the tricky bit. the sceneRect is the part of the scene you want to fit into the viewport rectangle.
                                      make it bigger in scene space and it looks smaller in the viewport and so on. You can make it scale automatically to the items in the scene or do it manually.

                                      U 1 Reply Last reply
                                      2
                                      • K kenchan

                                        @user4592357
                                        Yes well that is the tricky bit. the sceneRect is the part of the scene you want to fit into the viewport rectangle.
                                        make it bigger in scene space and it looks smaller in the viewport and so on. You can make it scale automatically to the items in the scene or do it manually.

                                        U Offline
                                        U Offline
                                        user4592357
                                        wrote on last edited by
                                        #38

                                        @kenchan
                                        this did the trick ():

                                        view->setSceneRect(scene()->sceneRect())
                                        

                                        and my last question. as you could see in the above pictures, the crosses' bounding rects may overlap. in that case, when, for example cursor is in bottom cross's bounding rect, and i try to touch the lower right part of above cross, the highlight for the above cross isn't displayed.

                                        is this issue solvable?

                                        K 1 Reply Last reply
                                        0
                                        • U user4592357

                                          @kenchan
                                          this did the trick ():

                                          view->setSceneRect(scene()->sceneRect())
                                          

                                          and my last question. as you could see in the above pictures, the crosses' bounding rects may overlap. in that case, when, for example cursor is in bottom cross's bounding rect, and i try to touch the lower right part of above cross, the highlight for the above cross isn't displayed.

                                          is this issue solvable?

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

                                          @user4592357
                                          Ok, now things might get a bit more complex. The selection is currently using the bounding box so when they overlap you need to do more work if you want to distinguish exactly which cross was hit. In this case the zValue of the items is making the one you drew last get the hit first? You can set the zValue when this is important for picking but I don't think it helps in this case :-).
                                          Please read the documentation about the QGraphicsItem (the c++ docs I guess). If you implement the shape() method you can use a QPainterPath to return a more accurate shape, in your case lines with a thickness. You need to make it look at the thin version of the line because that is what the user will be seeing and trying to pick. You can use contains() and collidesWithPath() etc. to get a more precise picking experience :-). You will probably want to use these different testing functions in the event before you decide that the cursor is actually hovering over your shape. This kind of testing can get slow for complex shapes and when you have many shapes to test, but the bounding box test filters out things pretty quickly.
                                          In the last resort you can implement you own geometric testing algorithms but you probably don't need to go that far, do you?

                                          I hope this all helps :-)

                                          U 1 Reply Last reply
                                          2

                                          • Login

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