Search code examples
pythonpyqtpyqt5qtstylesheetsqmdiarea

Removing icon and style of QMdiSubWindow


I notice that windows from QMdiarea needs to be style customized. I want to remove icon which appears on topleft of QMdiSubWindow widget and at the same time change this ugly blue color of window to something which look pretty good.

I have tried my setWindowsflag, but no effect.

The code:

class Mywindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Mywindow, self).__init__(parent)
        
        self.setMinimumSize(QtCore.QSize(800,600))
        self.setWindowTitle('Customized style')
        self.mdiarea = QtWidgets.QMdiArea()
        self.setCentralWidget(self.mdiarea)
        self.mdiarea.setWindowTitle('Test')
        
        self.window = QtWidgets.QWidget()        
        self.mdiarea.addSubWindow(self.window)

if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('Fusion')
    view = Mywindow()
    view.showMaximized()
    sys.exit(app.exec_())

Current Display:

enter image description here

Wants to obtain:

enter image description here

Any idea how to achieve that?


Solution

  • At least there are 2 solutions:

    1. Use Qt StyleSheet

    You must use the "background" property of QMdiSubWindow: title to change the color, and to remove the icon the trick is to pass it an icon with transparent color

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    QSS = """
    QMdiSubWindow:title{
        background: lightgray;
    }
    """
    
    
    def create_icon_by_color(color):
        pixmap = QtGui.QPixmap(512, 512)
        pixmap.fill(color)
        return QtGui.QIcon(pixmap)
    
    
    class Mywindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(Mywindow, self).__init__(parent)
            self.setWindowTitle("Customized style")
            self.mdiarea = QtWidgets.QMdiArea()
            self.setCentralWidget(self.mdiarea)
            self.mdiarea.setWindowTitle("Test")
    
            self.window = QtWidgets.QWidget()
            self.window.setMinimumSize(320, 240)
            sw = self.mdiarea.addSubWindow(self.window)
            sw.setWindowIcon(create_icon_by_color(QtGui.QColor("transparent")))
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        app.setStyle("Fusion")
        app.setStyleSheet(QSS)
        view = Mywindow()
        view.show()
        sys.exit(app.exec_())
    

    enter image description here

    As you can see in my operating system, it has a white color in the middle that is not desired that serves to color the title of the subwindow, maybe in another operating system it does not generate that problem.

    2. Use a QProxyStyle

    In this case you can modify the style so it should be a more robust solution than the previous one and should not have other styles. For a simple operation I have created a custom QMdiSubWindow.

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    def create_icon_by_color(color):
        pixmap = QtGui.QPixmap(512, 512)
        pixmap.fill(color)
        return QtGui.QIcon(pixmap)
    
    
    class TitleProxyStyle(QtWidgets.QProxyStyle):
        def drawComplexControl(self, control, option, painter, widget=None):
            if control == QtWidgets.QStyle.CC_TitleBar:
                if hasattr(widget, "titleColor"):
                    color = widget.titleColor
                    if color.isValid():
                        option.palette.setBrush(
                            QtGui.QPalette.Highlight, QtGui.QColor(color)
                        )
                option.icon = create_icon_by_color(QtGui.QColor("transparent"))
            super(TitleProxyStyle, self).drawComplexControl(
                control, option, painter, widget
            )
    
    
    class MdiSubWindow(QtWidgets.QMdiSubWindow):
        def __init__(self, parent=None, flags=QtCore.Qt.Widget):
            super(MdiSubWindow, self).__init__(parent, flags)
            style = TitleProxyStyle(self.style())
            self.setStyle(style)
            self._titleColor = QtGui.QColor()
    
        @property
        def titleColor(self):
            return self._titleColor
    
        @titleColor.setter
        def titleColor(self, color):
            self._titleColor = color
            self.update()
    
    
    class Mywindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(Mywindow, self).__init__(parent)
            self.setWindowTitle("Customized style")
            self.mdiarea = QtWidgets.QMdiArea()
            self.setCentralWidget(self.mdiarea)
            self.mdiarea.setWindowTitle("Test")
    
            self.window = QtWidgets.QWidget()
            self.window.setMinimumSize(160, 120)
    
            sw = MdiSubWindow()
            sw.setWindowTitle("Test")
            sw.titleColor = QtGui.QColor("lightgray")
            sw.setWidget(self.window)
            self.mdiarea.addSubWindow(sw)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        app.setStyle("Fusion")
        view = Mywindow()
        view.show()
        sys.exit(app.exec_())
    

    enter image description here