Search code examples
qtbackgroundpyqtpysideqgraphicsview

Painting background on QGraphicsView using drawBackground


I have a problem trying to paint and draw on QGraphicsView/Scene. I'm drawing a bunch of QLineF as background overridingQGraphicsView::drawBackGround`. However, when I try to change the background color nothing happens.

Here is minimal example of what I'm doing:

import sys
import platform
import ctypes
from PySide import QtCore, QtGui
from mygv import Ui_Dialog
import sys

class myView(QtGui.QDialog):
    def __init__(self, parent = None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.view.drawBackground = self.drawBackground
        self.ui.view.wheelEvent = self.wheelEvent
        self.scene = QtGui.QGraphicsScene()
        self.ui.view.setScene(self.scene)
        self.scene.addEllipse(0,0,100,100)

    def drawBackground(self, painter, rect):

        bbrush = QtGui.QBrush( QtGui.QColor(255,170,255), QtCore.Qt.SolidPattern)
        painter.setBackgroundMode(QtCore.Qt.OpaqueMode)

        pen = QtGui.QPen(QtGui.QColor(46, 84, 255))
        pen.setWidth(5)
        painter.setPen(pen)

        line1 = QtCore.QLineF(0,0,0,100)
        line2 = QtCore.QLineF(0,100,100,100)
        line3 = QtCore.QLineF(100,100,100,0)
        line4 = QtCore.QLineF(100,0,0,0)
        painter.setBackground(bbrush)
        painter.drawLines([line1, line2, line3, line4])




    def wheelEvent(self,event):
        factor = 1.41 ** (event.delta() / 240.0)
        self.ui.view.scale(factor, factor)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    diag = myView()
    diag.show()
    diag.ui.view.centerOn(50,50)
    app.exec_()

Ui_dialog is just a standard dialog generated from QDesigner with a QGraphicsView member named "view".

This just an example of the problem. I need to be able to change the color of the background systematically during the execution of my app.

What am I missing or doing (clearly) wrong?


Solution

  • The setBackground method of the QPainter does not fill the background but only specifies the background for operations like drawing opaque text, stippled lines and bitmaps (see the documentation).

    You can use fillRect instead to first fill a rectangle of the size of your paintable area with the brush you specified.

    Example:

    import sys
    from PyQt5 import QtCore, QtWidgets, QtGui
    
    class myView(QtWidgets.QGraphicsView):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def drawBackground(self, painter, rect):
    
            background_brush = QtGui.QBrush( QtGui.QColor(255,170,255), QtCore.Qt.SolidPattern)
            painter.fillRect(rect, background_brush)
    
            pen = QtGui.QPen(QtGui.QColor(46, 84, 255))
            pen.setWidth(5)
            painter.setPen(pen)
    
            line1 = QtCore.QLineF(0,0,0,100)
            line2 = QtCore.QLineF(0,100,100,100)
            line3 = QtCore.QLineF(100,100,100,0)
            line4 = QtCore.QLineF(100,0,0,0)
            painter.drawLines([line1, line2, line3, line4])
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
    
        scene = QtWidgets.QGraphicsScene()
        scene.addEllipse(0,0,100,100)
    
        view = myView(scene)
        view.show()
        view.centerOn(50,50)
    
        app.exec_()
    

    It uses PyQt5 but is fairly straightforward to understand.

    Result:

    enter image description here

    shows the nice magenta color you specified.