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. Fixed Content on QGraphicsview
Forum Updated to NodeBB v4.3 + New Features

Fixed Content on QGraphicsview

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 2 Posters 3.6k Views 1 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.
  • J Offline
    J Offline
    justStartedQt
    wrote on last edited by
    #1

    Hi,
    I am trying to paint some extra content on top of my custom GraphicsView. The goal is to have a Vignette-Effect over the displayed Scene. Of course the overlay should be fixed to the View.

    0_1513698774080_VignetteExample.png

    What I tryed so far:

    • reimplementing drawForeground()
      - this solution would internally add new Items to the actual Scene. I would have to handle this special Items for every transformation of the Scene to keep it static. (And I didn't really get it work properly)
      But especially I guess this is not the way Scenes, View and Items should be handled. It would be better not to mix Vignette-Items with Scene-Content.

    • reimplementing paintEvent()
      - maybe a bad idea: I tried to reimplement the paintEvent(), calling the parents paintEvent first to let it draw the Scene

    • Stylesheets
      - I dont have much experience with Stylesheets and I am not sure if it is even possible with a GraphicsView.
      In my case the stylesheet doesn't seem to have any effect, maybe because the Scene is drawn on top?

    • Another QWidget on top
      - this would be a really ugly hack

    Does someone have a (rough) idea, how to achieve that Effect?
    Is there a regular way of doing this?

    I am open for every hint, idea and suggestion.
    Thank you so much,
    justStartedQt

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      @justStartedQt said in Fixed Content on QGraphicsview:

      Vignette-Effect

      Like the grey button like seen in your image ?
      Also behind any object Items?
      I googled Vignette-Effect and it seems to mean darken in the corners but
      is that what you mean ?

      I have never tried with stylesheet so i dont know if it stay fixed if you rotate the view
      but it does draw.
      alt text

      Update:
      Seems to stay fixed
      alt text

      1 Reply Last reply
      0
      • J Offline
        J Offline
        justStartedQt
        wrote on last edited by
        #3

        Hi, thank you for the fast answer.
        My Picture was maybe not as good. I thought about a Border on top of the Scene/Items. The Gradient would be transparent in the inside and opaque outside. So the Scene/Items "disappear" when coming to the edges. I will just make another quick drawing. - Thanks

        mrjjM 1 Reply Last reply
        0
        • J justStartedQt

          Hi, thank you for the fast answer.
          My Picture was maybe not as good. I thought about a Border on top of the Scene/Items. The Gradient would be transparent in the inside and opaque outside. So the Scene/Items "disappear" when coming to the edges. I will just make another quick drawing. - Thanks

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @justStartedQt
          ok so it must be in front/over the items.
          That rules out stylesheet as they are behind.
          So the items should sort of fade in the corners.

          Im reading about
          void setForegroundBrush(const QBrush & brush)
          maybe that can do it
          http://doc.qt.io/qt-5/qgraphicsview.html#foregroundBrush-prop
          says gradient possible.

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi
            Nope
            foregroundBrush scales with the view so gradient would also
            alt text

            1 Reply Last reply
            0
            • J Offline
              J Offline
              justStartedQt
              wrote on last edited by
              #6

              The Picture for the sake of completeness:

              0_1513703623122_VignetteExample.png

              As far as I understand, the ForegroundBrush controlls only the behavior of the drawForeground-function. The function creates new content in the QGraphicsScene::ForegroundLayer instead of the ItemLayer. The same function can be accessed trough the Graphicsview.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                justStartedQt
                wrote on last edited by
                #7

                Hi,
                is it maybe possible to reimplement QGraphicsView::paintEvent?
                I tryed to call the parent function first, to let it draw the Scene. But it seemed impossible to add a new QPainter/use the old one.
                Thank you for your efforts.

                mrjjM 1 Reply Last reply
                0
                • J justStartedQt

                  Hi,
                  is it maybe possible to reimplement QGraphicsView::paintEvent?
                  I tryed to call the parent function first, to let it draw the Scene. But it seemed impossible to add a new QPainter/use the old one.
                  Thank you for your efforts.

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @justStartedQt
                  I think
                  GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
                  is the best way but one issue is that the rect is the dirty rect and since
                  view can be huge the fade effect should draw "just big enough" with outscaling.
                  I wondering if one of the QGraphicsEffect can do it.

                  Its clearly possible with
                  drawForeground
                  alt text
                  But we need some sort of translate or scaling to make it be static as it
                  scales with the view.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    justStartedQt
                    wrote on last edited by
                    #9

                    Hi,
                    I gave it a try:

                    GraphicsView::GraphicsView()
                    {
                    	vignetteLeftGradient = QLinearGradient(0, 0, VignetteWidth, 0); 
                                                               // setting gradients coordinates
                    	vignetteLeftGradient.setColorAt(0, QColor(0, 0, 255, 255));
                    	vignetteLeftGradient.setColorAt(1, QColor(255, 0, 0, 255));
                    	vignetteLeftBrush = QBrush(vignetteLeftGradient);
                    }
                    
                    
                    void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
                    {
                    	painter->setBrush(vignetteLeftBrush);
                    	painter->drawConvexPolygon(vignetteLeftPoints, 4);
                    }
                    
                    
                    void GraphicsView::resizeEvent(QResizeEvent *event)
                    {
                    	recalcVignetteGeometry();
                    }
                    
                    void GraphicsView::recalcVignetteGeometry()
                    {
                    	vignetteLeftPoints[0] = mapToScene(0, 0);
                    	vignetteLeftPoints[1] = mapToScene(VignetteWidth, VignetteWidth);
                    	vignetteLeftPoints[2] = mapToScene(VignetteWidth, height() - VignetteWidth);
                    	vignetteLeftPoints[3] = mapToScene(0, height());
                    }
                    

                    The result:

                    0_1513705737876_drawForegroundTest.png

                    The gradient does not appear. I think there is a problem with setting the gradients position.
                    Is the gradient part of the Scene and do I have to map it to Scene-Coordinates?
                    Do I have to use another QGradient::CoordinateMode?

                    The big disadvantage is maybe, that one has to manage all transformations manually.

                    mrjjM 1 Reply Last reply
                    0
                    • J justStartedQt

                      Hi,
                      I gave it a try:

                      GraphicsView::GraphicsView()
                      {
                      	vignetteLeftGradient = QLinearGradient(0, 0, VignetteWidth, 0); 
                                                                 // setting gradients coordinates
                      	vignetteLeftGradient.setColorAt(0, QColor(0, 0, 255, 255));
                      	vignetteLeftGradient.setColorAt(1, QColor(255, 0, 0, 255));
                      	vignetteLeftBrush = QBrush(vignetteLeftGradient);
                      }
                      
                      
                      void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
                      {
                      	painter->setBrush(vignetteLeftBrush);
                      	painter->drawConvexPolygon(vignetteLeftPoints, 4);
                      }
                      
                      
                      void GraphicsView::resizeEvent(QResizeEvent *event)
                      {
                      	recalcVignetteGeometry();
                      }
                      
                      void GraphicsView::recalcVignetteGeometry()
                      {
                      	vignetteLeftPoints[0] = mapToScene(0, 0);
                      	vignetteLeftPoints[1] = mapToScene(VignetteWidth, VignetteWidth);
                      	vignetteLeftPoints[2] = mapToScene(VignetteWidth, height() - VignetteWidth);
                      	vignetteLeftPoints[3] = mapToScene(0, height());
                      }
                      

                      The result:

                      0_1513705737876_drawForegroundTest.png

                      The gradient does not appear. I think there is a problem with setting the gradients position.
                      Is the gradient part of the Scene and do I have to map it to Scene-Coordinates?
                      Do I have to use another QGradient::CoordinateMode?

                      The big disadvantage is maybe, that one has to manage all transformations manually.

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by mrjj
                      #10

                      @justStartedQt
                      Im not sure how to get make it static.
                      Seems to scale regards less of that i do.

                      Update:
                      found it.
                      alt text

                      void GraphicsView::drawForeground(QPainter* painter, const QRectF& rect) {
                        QRectF area ( mapToScene(viewport()->geometry()).boundingRect());
                        QRadialGradient radialGrad(area.center(), area.width());
                        radialGrad.setColorAt(0, Qt::white);
                        radialGrad.setColorAt(0.5, Qt::green);
                        radialGrad.setColorAt(1, Qt::black);
                        painter->setOpacity(0.9);
                        painter->fillRect(area, radialGrad);
                      }
                      
                      

                      Its not quite there i know but it wont scale with view and
                      if you tweak the QRadialGradient it should work. ( i hope) :)

                      1 Reply Last reply
                      2
                      • J Offline
                        J Offline
                        justStartedQt
                        wrote on last edited by
                        #11

                        @mrjj
                        I FINALLY GOT IT!

                        0_1513778240878_Vignette.png

                        It does work with resizing and hopefully also with SceneTransformations by simply calling recalcVignetteGeometry() again.

                        For everyone who wants to do something similar:

                        graphicsview.h

                        #ifndef GRAPHICSVIEW_H
                        #define GRAPHICSVIEW_H
                        
                        #include <QGraphicsView>
                        
                        class GraphicsView : public QGraphicsView
                        {
                        	public:
                        		GraphicsView();
                        		void drawForeground(QPainter *painter, const QRectF &rect);
                        		void resizeEvent(QResizeEvent *event);
                        		void init();
                        
                        	private:
                        		// Vignette:
                        		void recalcVignetteGeometry();
                        		const int VignetteWidth = 50;
                        		const QColor vInnerColor = QColor(22, 22, 22, 0);
                        		const QColor vOuterColor = QColor(22, 22, 22, 255);
                        
                        		// -Left:
                        		QPointF vLeftPoints[4];
                        		QLinearGradient vLeftGradient;
                        
                        		// -Top:
                        		QPointF vTopPoints[4];
                        		QLinearGradient vTopGradient;
                        
                        		// -Right:
                        		QPointF vRightPoints[4];
                        		QLinearGradient vRightGradient;
                        
                        		// -Bottom:
                        		QPointF vBottomPoints[4];
                        		QLinearGradient vBottomGradient;
                        
                        };
                        
                        #endif // GRAPHICSVIEW_H
                        

                        graphicsview.cpp

                        #include "graphicsview.h"
                        
                        GraphicsView::GraphicsView()
                        {
                        	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                        	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                        
                        	vLeftGradient.setColorAt(0, vOuterColor);
                        	vLeftGradient.setColorAt(1, vInnerColor);
                        
                        	vTopGradient.setColorAt(0, vOuterColor);
                        	vTopGradient.setColorAt(1, vInnerColor);
                        
                        	vRightGradient.setColorAt(0, vOuterColor);
                        	vRightGradient.setColorAt(1, vInnerColor);
                        
                        	vBottomGradient.setColorAt(0, vOuterColor);
                        	vBottomGradient.setColorAt(1, vInnerColor);
                        }
                        
                        
                        void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
                        {
                        	painter->setPen(Qt::NoPen);
                        
                        	// Left
                        	QBrush vLeftBrush(vLeftGradient);
                        	painter->setBrush(vLeftBrush);
                        	painter->drawConvexPolygon(vLeftPoints, 4);
                        
                        	// Top
                        	QBrush vTopBrush(vTopGradient);
                        	painter->setBrush(vTopBrush);
                        	painter->drawConvexPolygon(vTopPoints, 4);
                        
                        	// Right
                        	QBrush vRightBrush(vRightGradient);
                        	painter->setBrush(vRightBrush);
                        	painter->drawConvexPolygon(vRightPoints, 4);
                        
                        	// Bottom
                        	QBrush vBottomBrush(vBottomGradient);
                        	painter->setBrush(vBottomBrush);
                        	painter->drawConvexPolygon(vBottomPoints, 4);
                        }
                        
                        
                        void GraphicsView::recalcVignetteGeometry()
                        {
                        	// Left
                        	vLeftPoints[0] = mapToScene(0, 0);
                        	vLeftPoints[1] = mapToScene(VignetteWidth, VignetteWidth);
                        	vLeftPoints[2] = mapToScene(VignetteWidth, height() - VignetteWidth);
                        	vLeftPoints[3] = mapToScene(0, height());
                        
                        	vLeftGradient.setStart(mapToScene(0, 0).x(), 0);
                        	vLeftGradient.setFinalStop(mapToScene(VignetteWidth, 0).x(), 0);
                        
                        	// Top
                        	vTopPoints[0] = mapToScene(width(), 0);
                        	vTopPoints[1] = mapToScene(width() - VignetteWidth, VignetteWidth);
                        	vTopPoints[2] = mapToScene(VignetteWidth, VignetteWidth);
                        	vTopPoints[3] = mapToScene(0, 0);
                        
                        	vTopGradient.setStart(0, mapToScene(0, 0).y());
                        	vTopGradient.setFinalStop(0, mapToScene(0, VignetteWidth).y());
                        
                        	// Right
                        	vRightPoints[0] = mapToScene(width(), height());
                        	vRightPoints[1] = mapToScene(width() - VignetteWidth, height() - VignetteWidth);
                        	vRightPoints[2] = mapToScene(width() - VignetteWidth, VignetteWidth);
                        	vRightPoints[3] = mapToScene(width(), 0);
                        
                        	vRightGradient.setStart(mapToScene(width(), 0).x(), 0);
                        	vRightGradient.setFinalStop(mapToScene(width() - VignetteWidth, 0).x(), 0);
                        
                        	// Bottom
                        	vBottomPoints[0] = mapToScene(0, height());
                        	vBottomPoints[1] = mapToScene(VignetteWidth, height() - VignetteWidth);
                        	vBottomPoints[2] = mapToScene(width() - VignetteWidth, height() - VignetteWidth);
                        	vBottomPoints[3] = mapToScene(width(), height());
                        
                        	vBottomGradient.setStart(0, mapToScene(0, height()).y());
                        	vBottomGradient.setFinalStop(0, mapToScene(0, height() - VignetteWidth).y());
                        }
                        
                        
                        void GraphicsView::resizeEvent(QResizeEvent *event)
                        {
                        	recalcVignetteGeometry();
                        }
                        

                        Thank you so much @mrjj !
                        You are definitely my Champion of the Year,
                        justStartedQt

                        mrjjM 1 Reply Last reply
                        0
                        • J justStartedQt

                          @mrjj
                          I FINALLY GOT IT!

                          0_1513778240878_Vignette.png

                          It does work with resizing and hopefully also with SceneTransformations by simply calling recalcVignetteGeometry() again.

                          For everyone who wants to do something similar:

                          graphicsview.h

                          #ifndef GRAPHICSVIEW_H
                          #define GRAPHICSVIEW_H
                          
                          #include <QGraphicsView>
                          
                          class GraphicsView : public QGraphicsView
                          {
                          	public:
                          		GraphicsView();
                          		void drawForeground(QPainter *painter, const QRectF &rect);
                          		void resizeEvent(QResizeEvent *event);
                          		void init();
                          
                          	private:
                          		// Vignette:
                          		void recalcVignetteGeometry();
                          		const int VignetteWidth = 50;
                          		const QColor vInnerColor = QColor(22, 22, 22, 0);
                          		const QColor vOuterColor = QColor(22, 22, 22, 255);
                          
                          		// -Left:
                          		QPointF vLeftPoints[4];
                          		QLinearGradient vLeftGradient;
                          
                          		// -Top:
                          		QPointF vTopPoints[4];
                          		QLinearGradient vTopGradient;
                          
                          		// -Right:
                          		QPointF vRightPoints[4];
                          		QLinearGradient vRightGradient;
                          
                          		// -Bottom:
                          		QPointF vBottomPoints[4];
                          		QLinearGradient vBottomGradient;
                          
                          };
                          
                          #endif // GRAPHICSVIEW_H
                          

                          graphicsview.cpp

                          #include "graphicsview.h"
                          
                          GraphicsView::GraphicsView()
                          {
                          	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                          	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                          
                          	vLeftGradient.setColorAt(0, vOuterColor);
                          	vLeftGradient.setColorAt(1, vInnerColor);
                          
                          	vTopGradient.setColorAt(0, vOuterColor);
                          	vTopGradient.setColorAt(1, vInnerColor);
                          
                          	vRightGradient.setColorAt(0, vOuterColor);
                          	vRightGradient.setColorAt(1, vInnerColor);
                          
                          	vBottomGradient.setColorAt(0, vOuterColor);
                          	vBottomGradient.setColorAt(1, vInnerColor);
                          }
                          
                          
                          void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
                          {
                          	painter->setPen(Qt::NoPen);
                          
                          	// Left
                          	QBrush vLeftBrush(vLeftGradient);
                          	painter->setBrush(vLeftBrush);
                          	painter->drawConvexPolygon(vLeftPoints, 4);
                          
                          	// Top
                          	QBrush vTopBrush(vTopGradient);
                          	painter->setBrush(vTopBrush);
                          	painter->drawConvexPolygon(vTopPoints, 4);
                          
                          	// Right
                          	QBrush vRightBrush(vRightGradient);
                          	painter->setBrush(vRightBrush);
                          	painter->drawConvexPolygon(vRightPoints, 4);
                          
                          	// Bottom
                          	QBrush vBottomBrush(vBottomGradient);
                          	painter->setBrush(vBottomBrush);
                          	painter->drawConvexPolygon(vBottomPoints, 4);
                          }
                          
                          
                          void GraphicsView::recalcVignetteGeometry()
                          {
                          	// Left
                          	vLeftPoints[0] = mapToScene(0, 0);
                          	vLeftPoints[1] = mapToScene(VignetteWidth, VignetteWidth);
                          	vLeftPoints[2] = mapToScene(VignetteWidth, height() - VignetteWidth);
                          	vLeftPoints[3] = mapToScene(0, height());
                          
                          	vLeftGradient.setStart(mapToScene(0, 0).x(), 0);
                          	vLeftGradient.setFinalStop(mapToScene(VignetteWidth, 0).x(), 0);
                          
                          	// Top
                          	vTopPoints[0] = mapToScene(width(), 0);
                          	vTopPoints[1] = mapToScene(width() - VignetteWidth, VignetteWidth);
                          	vTopPoints[2] = mapToScene(VignetteWidth, VignetteWidth);
                          	vTopPoints[3] = mapToScene(0, 0);
                          
                          	vTopGradient.setStart(0, mapToScene(0, 0).y());
                          	vTopGradient.setFinalStop(0, mapToScene(0, VignetteWidth).y());
                          
                          	// Right
                          	vRightPoints[0] = mapToScene(width(), height());
                          	vRightPoints[1] = mapToScene(width() - VignetteWidth, height() - VignetteWidth);
                          	vRightPoints[2] = mapToScene(width() - VignetteWidth, VignetteWidth);
                          	vRightPoints[3] = mapToScene(width(), 0);
                          
                          	vRightGradient.setStart(mapToScene(width(), 0).x(), 0);
                          	vRightGradient.setFinalStop(mapToScene(width() - VignetteWidth, 0).x(), 0);
                          
                          	// Bottom
                          	vBottomPoints[0] = mapToScene(0, height());
                          	vBottomPoints[1] = mapToScene(VignetteWidth, height() - VignetteWidth);
                          	vBottomPoints[2] = mapToScene(width() - VignetteWidth, height() - VignetteWidth);
                          	vBottomPoints[3] = mapToScene(width(), height());
                          
                          	vBottomGradient.setStart(0, mapToScene(0, height()).y());
                          	vBottomGradient.setFinalStop(0, mapToScene(0, height() - VignetteWidth).y());
                          }
                          
                          
                          void GraphicsView::resizeEvent(QResizeEvent *event)
                          {
                          	recalcVignetteGeometry();
                          }
                          

                          Thank you so much @mrjj !
                          You are definitely my Champion of the Year,
                          justStartedQt

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @justStartedQt

                          Super Good work ! \o/
                          Thank you for posting code.
                          Hehe thank you. If i do not win this year, its a good comfort :)

                          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