删除 QMdiSubWindow 的图标和样式
Removing icon and style of QMdiSubWindow
我注意到 QMdiarea 中的 windows 需要自定义样式。我想删除出现在 QMdiSubWindow 小部件左上角的图标,同时将 window 的丑陋蓝色更改为看起来不错的颜色。
我试过我的 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_())
当前显示:
想要获得:
知道如何实现吗?
试一试:
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_())
至少有2种解法:
1.使用 Qt 样式表
你必须使用 QMdiSubWindow 的 "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_())
我注意到 QMdiarea 中的 windows 需要自定义样式。我想删除出现在 QMdiSubWindow 小部件左上角的图标,同时将 window 的丑陋蓝色更改为看起来不错的颜色。
我试过我的 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_())
当前显示:
想要获得:
知道如何实现吗?
试一试:
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_())
至少有2种解法:
1.使用 Qt 样式表
你必须使用 QMdiSubWindow 的 "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_())