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. Adding QGraphicsItem at View Coordinates
Forum Updated to NodeBB v4.3 + New Features

Adding QGraphicsItem at View Coordinates

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 1.8k 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.
  • S Offline
    S Offline
    Strangelove
    wrote on 22 Jul 2021, 21:04 last edited by
    #1

    Hi,

    What's the simplest way to add a QGraphicsItem to a QGraphicsScene so that it's always visible at a fixed, absolute position relative to the view coordinates (such as a FPS counter)?

    I can't understand from the documentation if I'm supposed to juggle stuff around with map from/to scene or if there's a simpler way.

    Thanks.

    J E 2 Replies Last reply 22 Jul 2021, 21:54
    0
    • S Strangelove
      22 Jul 2021, 21:04

      Hi,

      What's the simplest way to add a QGraphicsItem to a QGraphicsScene so that it's always visible at a fixed, absolute position relative to the view coordinates (such as a FPS counter)?

      I can't understand from the documentation if I'm supposed to juggle stuff around with map from/to scene or if there's a simpler way.

      Thanks.

      J Offline
      J Offline
      JonB
      wrote on 22 Jul 2021, 21:54 last edited by JonB
      #2

      @Strangelove
      You want to show something at, say, the top-left of any view, regardless of where on the scene the view is showing, like say a counter or a logo, right? And probably independent of any zooming? I hope I'm right, but this doesn't sound line a QGraphicsItem to me. That is an object on the scene. If you did that, you'd have to move it as the view moved around the scene? You just have an "artefact" on the view? I assume the would be best implemented via QGraphicsView::drawForeground():

      Draws the foreground of the scene using painter, after the background and all items are drawn. Reimplement this function to provide a custom foreground for this view.

      Actually, if you want it present in any view, same principle but on the scene QGraphicsScene::drawForeground():

      Draws the foreground of the scene using painter, after the background and all items have been drawn. Reimplement this function to provide a custom foreground for the scene.

      But I have feeling you want it on the view....

      S 1 Reply Last reply 23 Jul 2021, 06:06
      0
      • S Strangelove
        22 Jul 2021, 21:04

        Hi,

        What's the simplest way to add a QGraphicsItem to a QGraphicsScene so that it's always visible at a fixed, absolute position relative to the view coordinates (such as a FPS counter)?

        I can't understand from the documentation if I'm supposed to juggle stuff around with map from/to scene or if there's a simpler way.

        Thanks.

        E Offline
        E Offline
        eyllanesc
        wrote on 22 Jul 2021, 22:11 last edited by
        #3

        @Strangelove There are several alternative solutions but it will depend on your objective of that item.

        • A possible solution is to do the custom painting (they are not QGraphicsItems) override the drawForeground method.

        • Instead of using a QGraphicsItem you can use a QWidget on top of the viewport(parent):

        FooWidget *widget = new FooWidget(graphicsView->viewport());
        

        OR

        FooWidget *widget = new FooWidget()
        widget->setParent(graphicsView->viewport());
        

        If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

        1 Reply Last reply
        0
        • J JonB
          22 Jul 2021, 21:54

          @Strangelove
          You want to show something at, say, the top-left of any view, regardless of where on the scene the view is showing, like say a counter or a logo, right? And probably independent of any zooming? I hope I'm right, but this doesn't sound line a QGraphicsItem to me. That is an object on the scene. If you did that, you'd have to move it as the view moved around the scene? You just have an "artefact" on the view? I assume the would be best implemented via QGraphicsView::drawForeground():

          Draws the foreground of the scene using painter, after the background and all items are drawn. Reimplement this function to provide a custom foreground for this view.

          Actually, if you want it present in any view, same principle but on the scene QGraphicsScene::drawForeground():

          Draws the foreground of the scene using painter, after the background and all items have been drawn. Reimplement this function to provide a custom foreground for the scene.

          But I have feeling you want it on the view....

          S Offline
          S Offline
          Strangelove
          wrote on 23 Jul 2021, 06:06 last edited by Strangelove
          #4

          @JonB said in Adding QGraphicsItem at View Coordinates:

          like say a counter or a logo, right?

          Right.

          I've tried the following but apparently I misunderstood the purpose of drawForeground, as this object is transformed together with the scene like any other object:

              def drawForeground(self, painter: QPainter, rect):
                  painter.setPen(QPen(QColor('white')))
                  painter.drawEllipse(0, 0, 50, 50)
                  return super().drawForeground(painter, rect)
          

          Isn't there a simple way to just draw a static stenciled item using view coordinates?

          J E 2 Replies Last reply 23 Jul 2021, 08:30
          0
          • S Strangelove
            23 Jul 2021, 06:06

            @JonB said in Adding QGraphicsItem at View Coordinates:

            like say a counter or a logo, right?

            Right.

            I've tried the following but apparently I misunderstood the purpose of drawForeground, as this object is transformed together with the scene like any other object:

                def drawForeground(self, painter: QPainter, rect):
                    painter.setPen(QPen(QColor('white')))
                    painter.drawEllipse(0, 0, 50, 50)
                    return super().drawForeground(painter, rect)
            

            Isn't there a simple way to just draw a static stenciled item using view coordinates?

            J Offline
            J Offline
            JonB
            wrote on 23 Jul 2021, 08:30 last edited by JonB
            #5

            @Strangelove said in Adding QGraphicsItem at View Coordinates:

            as this object is transformed together with the scene like any other object

            I don't know about this, you may have to untransform. But is this an override of QGraphicsView.drawForeground or of QGraphicsScene.drawForeground?

            As a small point, because you want yours on top of anything I would call super().drawForeground(painter, rect) base class before drawing your own stuff rather than afterwards.

            S 1 Reply Last reply 24 Jul 2021, 07:35
            0
            • J JonB
              23 Jul 2021, 08:30

              @Strangelove said in Adding QGraphicsItem at View Coordinates:

              as this object is transformed together with the scene like any other object

              I don't know about this, you may have to untransform. But is this an override of QGraphicsView.drawForeground or of QGraphicsScene.drawForeground?

              As a small point, because you want yours on top of anything I would call super().drawForeground(painter, rect) base class before drawing your own stuff rather than afterwards.

              S Offline
              S Offline
              Strangelove
              wrote on 24 Jul 2021, 07:35 last edited by
              #6

              @JonB said in Adding QGraphicsItem at View Coordinates:

              But is this an override of QGraphicsView.drawForeground or of QGraphicsScene.drawForeground

              It's an override of QGraphicsView. I don't know why it's using scene coordinates.

              1 Reply Last reply
              0
              • LeoCL Offline
                LeoCL Offline
                LeoC
                wrote on 26 Jul 2021, 14:45 last edited by
                #7

                I am still not very familiar with the graphics stuff in Qt but what about just using something like QRec?
                You just put some coordinates to it and then draw it with QPainter.

                QRect::QRect(int x, int y, int width, int height)
                

                https://doc.qt.io/qt-5/qrect.html

                S 1 Reply Last reply 29 Jul 2021, 21:56
                0
                • LeoCL LeoC
                  26 Jul 2021, 14:45

                  I am still not very familiar with the graphics stuff in Qt but what about just using something like QRec?
                  You just put some coordinates to it and then draw it with QPainter.

                  QRect::QRect(int x, int y, int width, int height)
                  

                  https://doc.qt.io/qt-5/qrect.html

                  S Offline
                  S Offline
                  Strangelove
                  wrote on 29 Jul 2021, 21:56 last edited by Strangelove
                  #8

                  @LeoC I added the following to the QWidget that contains the QGraphicsView (inside a BoxLayout), but no line was added to the widget:

                      def paintEvent(self, event):
                          qp = QPainter()
                          qp.begin(self)
                          pen = QPen()
                          pen.setColor('red')
                          qp.setPen(pen)
                          qp.drawText(20, 15, 'HELLO')
                          qp.end()
                  

                  I tried adding it to the QGraphicsView itself but, as I was expecting, the result was worse (the view stopped working and didn't display anything at all).

                  EDIT: The text does get drawn on the part of the widget which is just outside the QGraphicsView (the blue grid in the screenshot below). It doesn't get draw on the view itself (which is what I'm trying to achieve).

                  Screenshot 2021-07-29 at 23.59.38.jpg

                  1 Reply Last reply
                  0
                  • S Strangelove
                    23 Jul 2021, 06:06

                    @JonB said in Adding QGraphicsItem at View Coordinates:

                    like say a counter or a logo, right?

                    Right.

                    I've tried the following but apparently I misunderstood the purpose of drawForeground, as this object is transformed together with the scene like any other object:

                        def drawForeground(self, painter: QPainter, rect):
                            painter.setPen(QPen(QColor('white')))
                            painter.drawEllipse(0, 0, 50, 50)
                            return super().drawForeground(painter, rect)
                    

                    Isn't there a simple way to just draw a static stenciled item using view coordinates?

                    E Offline
                    E Offline
                    eyllanesc
                    wrote on 29 Jul 2021, 23:14 last edited by
                    #9

                    @Strangelove QPainter uses the coordinates of the scene for painting so the QRect (and any geometric elements) you use must be converted to that coordinate system.

                    from PyQt5 import QtCore, QtGui, QtWidgets
                    
                    
                    class GraphicsView(QtWidgets.QGraphicsView):
                        def drawForeground(self, painter, rect):
                            super().drawForeground(painter, rect)
                            rect = QtCore.QRect(0, 0, 50, 50)
                            point = QtCore.QPoint(20, 15)
                    
                            painter.setPen(QtGui.QPen(QtGui.QColor("white")))
                            painter.drawEllipse(self.mapToScene(rect).boundingRect())
                            painter.drawText(self.mapToScene(point), "HELLO")
                    
                    
                    def main():
                        import sys
                    
                        app = QtWidgets.QApplication(sys.argv)
                        scene = QtWidgets.QGraphicsScene()
                        view = GraphicsView(scene)
                        view.show()
                        sys.exit(app.exec_())
                    
                    
                    if __name__ == "__main__":
                        main()
                    

                    If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                    1 Reply Last reply
                    3

                    1/9

                    22 Jul 2021, 21:04

                    • Login

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