Search code examples
pythonsvgqtstylesheetspyside2

Displaying SVG as backround of QMainWindow in Pyside 2


I previously had difficulty setting a SVG as the background when I was using a simple QWidget as my main window. As suggested by another SO user, I overloaded the paintEvent() method of QWidget and was able to successfully display the SVG background.

However, I'm now working on a different application that needs a QStatusbar, therefore I'm using QMainWindow as the main window instead of QWidget. I tried the same approach of overloading the paintEvent() method to no avail. This is perplexing because the central widget that all QMainWindows have is just a QWidget. So specifying in the QSS that I want to make the SVG the background of the central widget shouldn't be a problem. Here's a Minimal, complete and verifiable example along with a screenshot of the QMainWindow I get.

from PySide2 import QtCore, QtGui, QtWidgets

class CustomWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(CustomWidget, self).__init__(parent)

    def paintEvent(self, event):

        opt = QtWidgets.QStyleOption()
        opt.init(self)
        painter = QtGui.QPainter(self)
        self.style().drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, painter, self)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)



        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.centralwidget = CustomWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        contents = b"<svg width='44' height='12' viewBox='0 0 44 12' xmlns='http://www.w3.org/2000/svg'><path d='M20 12v-2L0 0v10l4 2h16zm18 0l4-2V0L22 10v2h16zM20 0v8L4 0h16zm18 0L22 8V0h16z' fill='#2c2c2c' fill-opacity='0.4' fill-rule='evenodd'/></svg>"
        file = QtCore.QTemporaryFile(self.centralwidget)
        if file.open():
            file.write(contents)
            file.flush()
            self.centralwidget.setStyleSheet("""CustomWidget#Form{background-color: #000000;
                                  background-image: url(%s);}""" % file.fileName())
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))




if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

enter image description here


Solution

  • The problem is the selector in the stylesheet, in your case you have:

    CustomWidget#Form{...}
    

    In it you are indicating that these properties will be set to the CustomWidget whose objectname is Form, but in your case the CustomWidget objectname is centralwidget, so the solution is to change to:

    CustomWidget#centralwidget{...}
    

    enter image description here

    I recommend you check: