Results 1 to 4 of 4

Thread: QGraphicsView advantages of drawBackground and drawForeground?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jul 2017
    Posts
    2
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default QGraphicsView advantages of drawBackground and drawForeground?

    So I'm working on a map widget to place a drone on a map, and I don't understand all the existing code just yet. I'm wondering, as I can do

    Qt Code:
    1. QPainter(viewport());
    2. viewport()->rect();
    To copy to clipboard, switch view to plain text mode 

    to get a painter to draw things to the widget and to get the widget's geometric properties, what is the point of the functions void drawBackground(QPainter * painter, const QRectF & rect) and void drawForeground(QPainter * painter, const QRectF & rect) when one could just create their own functions to deal with specific events instead of 2 functions for all cases? Also, are these 2 functions called when the QGraphicsView recieves a call to update()?

    Is the benefit that when one calls drawForeground, it only replaces the items drawn in previous calls to drawForeground? In other words, If I were to draw a physical map of real world terrain in drawBackground, then call drawForeground each time the drone position changes, will it erase the drone drawn from the previous drawForeground before drawing another drone and without affecting the map? If I were to draw a picture from an image file with drawBackground that takes up the entire viewport, will it erase the stuff from the previous call to drawForeground?
    Last edited by Bla1; 21st July 2017 at 23:51.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QGraphicsView advantages of drawBackground and drawForeground?

    Your lines of code are nonsensical - the first line creates a QPainter instance on the stack but then doesn't assign it to any QPainter variable. The second line likewise reads the viewport rect and does nothing with it.

    You also seem to be confusing general QWidget painting with the specialized painting done in QGraphicsView. In both cases, painting occurs via the paintEvent(). In the case of QWidget, that's where it all occurs. In the case of QGraphicsView, the paintEvent() is divided into three stages:

    - the widget background is erased (unless autoFillBackground is set to false), followed by calls to
    - QGraphicsView::drawBackground() followed by
    - QGraphicsScene::render(), which uses the QPainter provided by the QGraphicsView to paint the scene into the viewport, followed by
    - QGraphicsView::drawForeground()

    In the base class QGraphicsView implementation, the drawBackground() and drawForeground() methods do nothing. They exist so that you can derive from QGraphicsView and draw things under or on top of the scene.

    So in your case, you might draw your map in drawBackground(), make your drone an object derived from QGraphicsItem in the scene (which is drawn next), and then draw text which updates the drone's velocity and position in a fixed place in the foreground that doesn't change relative either to the map or the drone's position in the scene.

    You also seem to be confused in thinking that the widget window is erased and completely replaced by whatever occurs in drawForeground() and drawBackground(). That's not what happens - the only time the window is erased is at the very beginning of the paint event. After that, everything else is layered on top of the blank window in the order I gave above. Neither the background, scene, or foreground have to fill the whole window with graphics, but the three layers -will- be painted on top of each other so scene elements will cover whatever is under them in the background, and foreground elements will cover whatever is under them in both the scene and background.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jul 2017
    Posts
    2
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QGraphicsView advantages of drawBackground and drawForeground?

    The QPainter and QRectF provided to drawBackground and drawForeground are the same ones you would get by calling:
    Qt Code:
    1. QPainter(viewport());
    2. viewport()->rect();
    To copy to clipboard, switch view to plain text mode 

    right?
    So, for example, if I had another function that was responsible for drawing a diagonal line across the widget, I could do something along the lines of

    Qt Code:
    1. void drawDiagonalLine(){
    2. QPainter a(viewport());
    3. a.drawLine(0,0,viewport()->rect().x(),viewport()->rect().y());
    4. }
    To copy to clipboard, switch view to plain text mode 

    That way, one wouldn't be completely dependent on drawForeground and drawBackground. I could also have special case helper functions that are only occasionally called that don't need the QPainter and QRectF from drawForeground/drawBackground, as I could get them each time.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QGraphicsView advantages of drawBackground and drawForeground?

    So, for example, if I had another function that was responsible for drawing a diagonal line across the widget, I could do something along the lines of
    No. You cannot do any drawing to the screen in Qt outside of the paintEvent() (or a function called while inside paintEvent()) of the QWidget in which you want to do the drawing (unless you have a custom QPaintEngine, which you will likely never have).

    Qt Code:
    1. QPainter(viewport());
    To copy to clipboard, switch view to plain text mode 
    There is no such QPainter constructor that simply takes a rect as an argument. QPainter always renders its output to a QPaintDevice instance you give it as a constructor argument, and the only place you can construct a QPainter to render to the screen is inside of the QWidget's paintEvent().

    You are never dependent on drawForeground() or drawBackground() if all you are drawing to the screen are QGraphicsItems added to a QGraphicsScene. These two functions exist only to provide you a "hook" into QGraphicView's paintEvent() processing so that you can draw things before the QGraphicsScene is rendered (drawBackground()) or after the scene is rendered (drawForeground()). The widget is a sandwich - background bread on the bottom, scene meat in the middle, and foreground bread on the top. If you just have meat, then you can omit the bread.

    Everything (background, scene, forground) is redrawn with every paintEvent(). The QPaintEvent::rect() and QPaintEvent::region() methods give you the part of the widget that needs to be repainted so you don't have to repaint the entire thing if your painting is complex. In most cases, most widgets repaint everything all the time because their painting needs are simple.

    Qt Code:
    1. a.drawLine(0,0,viewport()->rect().x(),viewport()->rect().y());
    To copy to clipboard, switch view to plain text mode 

    Even if you could do this, this code would not give you a diagonal line, it would give you a dot in the top left corner. (0, 0) is top left, and x() and y() return the left (0) and top (0) coordinates, respectively.
    Last edited by d_stranz; 25th July 2017 at 23:40.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. The following user says thank you to d_stranz for this useful post:

    Bla1 (26th July 2017)

Similar Threads

  1. What are the advantages of developing in Qt this 2017?
    By laurantx0ne in forum Qt Programming
    Replies: 3
    Last Post: 4th April 2017, 21:34
  2. QGraphicsView\Scene drawBackground bitmap as geomap
    By pethead in forum Qt Programming
    Replies: 1
    Last Post: 29th October 2010, 13:45
  3. Advantages of commercial Qt other than licensing rights.
    By babu198649 in forum General Discussion
    Replies: 6
    Last Post: 23rd September 2008, 13:51
  4. QPainter and QGraphicsView drawBackground() override
    By forrestfsu in forum Qt Programming
    Replies: 4
    Last Post: 5th December 2006, 15:52

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.