3

我注意到来自 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_())

当前显示:

在此处输入图像描述

想要获得:

在此处输入图像描述

知道如何实现吗?

4

2 回答 2

3

尝试一下:

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

在此处输入图像描述

于 2019-07-03T22:43:48.747 回答
3

至少有2个解决方案:

1.使用Qt样式表

您必须使用 QMdiSubWindow: title 的“背景”属性来更改颜色,并删除图标,诀窍是将其传递给透明颜色的图标

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

在此处输入图像描述

于 2019-07-03T22:58:54.750 回答