【问题标题】:Removing icon and style of QMdiSubWindow移除 QMdiSubWindow 的图标和样式
【发布时间】:2019-11-14 10:43:54
【问题描述】:

我注意到来自 QMdiarea 的窗口需要自定义样式。我想删除出现在 QMdiSubWindow 小部件左上角的图标,同时将这个难看的蓝色窗口更改为看起来不错的东西。

我尝试了我的 setWindowsflag,但没有效果。

代码:

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_())

当前显示:

想要获得:

知道如何实现吗?

【问题讨论】:

    标签: python pyqt pyqt5 qtstylesheets qmdiarea


    【解决方案1】:

    试试看:

    import sys
    from PyQt5.QtWidgets import (QApplication, QMainWindow, QAction, QMenuBar, QWidget,
                                 QMdiArea, QMdiSubWindow, QProxyStyle, QStyle, QVBoxLayout)
    from PyQt5.QtGui     import (QIcon, QPainter, QPalette, QPixmap)
    from PyQt5.QtCore    import Qt, QSize
    
    
    class MDIArea(QMdiArea):
        def __init__(self, *args, **kwargs):
            super(MDIArea, self).__init__(*args, **kwargs)  
            self.parent = args[0]
            self.background_pixmap = self.parent.pixmap 
            self.centered          = False
    
        def paintEvent(self, event):
            painter = QPainter()
            painter.begin(self.viewport())
            if not self.centered:
                painter.drawPixmap(0, 0, self.width(), self.height(), self.background_pixmap)
            painter.end()
    
    
    class Mywindow(QMainWindow):
        count = 1
        def __init__(self, parent=None):
            super(Mywindow, self).__init__(parent)
            self.setWindowTitle('Customized style')
            self.setWindowIcon(QIcon("im.png"))
    
    #        self.mdiarea = QMdiArea()
            self.pixmap = QPixmap()
            self.pixmap.load("im.png")
            self.mdiarea = MDIArea(self)
    
            self.setCentralWidget(self.mdiarea)
    #        self.mdiarea.setWindowTitle('Test')
    
            self.window = QWidget()   
            sub = QMdiSubWindow()
            sub.resize(QSize(200,200))
            sub.setAttribute(Qt.WA_DeleteOnClose)
            sub.setWidget(self.window) 
            sub.setWindowTitle("Test {}".format(self.count))            # +++
            sub.setWindowIcon(QIcon("im.png"))
    
            self.mdiarea.addSubWindow(sub)
            sub.show()          
    
    
    style = """
    QWidget {
        color: #ffdd00;
        background-color: #eee;
    }
    QMainWindow {
        color: #ffdd00;
        background-color: #ff3333;
    }
    """
    
    if __name__ == "__main__":
        app = QApplication([])
        app.setStyleSheet(style)          
    
    #    app.setStyle('Fusion')                                        # ---
    
        view = Mywindow()
    #    view.showMaximized()
        view.resize(500, 500)
        view.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 非常感谢您的努力和选择。我只想说,我更喜欢 QProxystyle 的选项。
    【解决方案2】:

    至少有2个解决方案:

    1.使用 Qt 样式表

    你必须使用 QMdiSubWindow:title 的 "background" 属性来改变颜色,要移除图标,诀窍是传递一个透明颜色的图标

    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_())
    

    正如您在我的操作系统中看到的那样,它在中间有一个白色,这是不希望为子窗口的标题着色的,也许在另一个操作系统中它不会产生这个问题。

    2。使用 QProxyStyle

    在这种情况下,您可以修改样式,使其成为比前一种更强大的解决方案,并且不应该有其他样式。对于一个简单的操作,我创建了一个自定义 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_())
    

    【讨论】:

    • 非常感谢您的解决方案。我个人更喜欢第二种解决方案。它看起来很完美。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多