Not able to overload paintEvent() for QMainWindow to display SVG as backround, despite being able to do so for QWidget
-
I'm trying to set an SVG as the background for my QMainWindow based application. Previously I was using QWidget for my application, but I switched over to QMainWindow because I needed a status bar. I was able to set an SVG as a background when I was using QWidget by overloading
paintEvent()
. However, I'm not able to use the same approach for QMainWindow. What gives? I've created an example for both a QMainWindow and QWidget based application below.from PySide2 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(400, 300) 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(Form) if file.open(): file.write(contents) file.flush() Form.setStyleSheet("""CustomWidget#Form{background-color: #000000; background-image: url(%s);}""" % file.fileName()) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1)) 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) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) Form = CustomWidget() ui = Ui_Form() ui.setupUi(Form) Form.show() sys.exit(app.exec_())
from PySide2 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) 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(MainWindow) if file.open(): file.write(contents) file.flush() MainWindow.setStyleSheet("""CustomWidget#Form{background-color: #000000; background-image: url(%s);}""" % file.fileName()) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") MainWindow.setCentralWidget(self.centralwidget) 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)) class CustomWidget(QtWidgets.QMainWindow): 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) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = CustomWidget() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
-
Hi
Didn't read the code.
Just wanted to ask.
You are aware of centralWidget() for main window.
Unless you set SVG to that, it will be hidden. -
I tried overloading
paintEvent()
for thecentralwidget()
as well, however the SVG still isn't displayed as the background. Here is the code for that attempt: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_())
-
Hi,
Why are you doing a custom paint event if you are going to set a background image by stylesheet ?
-
Hi,
Why are you doing a custom paint event if you are going to set a background image by stylesheet ?
@SGaist
Thanks for responding.I initially tried the approach of not overriding
paintEvent
and using a temporary file to store the svg for the backround-image attribute of the stylesheet. However, I still couldn't get the SVG to display. This post on stackoverflow seems to indicate Pyside2(which I'm using) is a special case that requires the overloading of PaintEvent to display the SVG. This solution worked for QWidget(as shown above) but not for QMainWindow which is weirdly inconsistent. Any idea? -
QMainWindow does a lot of stuff to handle everything it does, therefore depending on what you want to do with it, you should rather customise its central widget.