Python PyQt5如何将不同的QSTYLE应用于不同的小部件?

Python PyQt5如何将不同的QSTYLE应用于不同的小部件?,python,pyqt5,qtstylesheets,qstyle,Python,Pyqt5,Qtstylesheets,Qstyle,我试图制作多个不同于QStyleFactory提供的内置样式的小部件,但是当我运行代码时,它们看起来都是一样的。我怎样才能解决这个问题 从PyQt5导入QtWidgets、QtCore、QtGui 导入系统 类演示(QtWidgets.QMainWindow): def uuu init uuu(self,parent=None): super()。\uuuu init\uuuu(父级) self.container=qtwidts.QWidget() self.setCentralWidge

我试图制作多个不同于QStyleFactory提供的内置样式的小部件,但是当我运行代码时,它们看起来都是一样的。我怎样才能解决这个问题

从PyQt5导入QtWidgets、QtCore、QtGui
导入系统
类演示(QtWidgets.QMainWindow):
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
self.container=qtwidts.QWidget()
self.setCentralWidget(self.container)
self.layout=qtwidts.QVBoxLayout()
self.container.setLayout(self.layout)
self.btn=QtWidgets.QPushButton(“按钮”)
self.lw=qtwidts.QListWidget()
self.lw.addItems([“一”、“二”、“三”])
self.layout.addWidget(self.btn)
self.layout.addWidget(self.lw)
自我调整大小(400150)
self.show()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=qtwidts.QApplication(sys.argv)
小部件=[]
对于qtwidts.QStyleFactory.keys()中的样式名称:
demo=demo()
demo.setWindowTitle(样式名称)
style=qtwidts.QStyleFactory.create(样式名称)
演示设置样式(样式)
widgets.append(演示)
sys.exit(app.exec_())

文档中报告了在小部件上设置QStyle(而不是在整个应用程序上设置QStyle)的一个重要方面:

设置小部件的样式对现有或未来的小部件没有影响

所以,现在的情况是,您只在QMainWindow上设置样式,而孩子们将始终使用QApplication样式

您可以尝试手动设置现有子项的样式:

QtWidgets.QStyleFactory.keys()中的样式名称的
:
demo=demo()
demo.setWindowTitle(样式名称)
style=qtwidts.QStyleFactory.create(样式名称)
演示设置样式(样式)
对于demo.findChildren(qtwidts.QWidget)中的子级:
child.setStyle(样式)
widgets.append(演示)
在任何情况下,上述方法都有一个缺点:设置样式后创建的任何新子级仍将继承QApplication样式。避免这种情况的唯一方法是(递归地)在父级上安装事件过滤器,并相应地设置样式;请注意,您还需要注意
StyleChange
事件

class ChildEventWatcher(QtCore.QObject):
    def __init__(self, parentWidget):
        super().__init__()
        self.parentWidget = parentWidget
        self.parentWidget.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.ChildAdded and isinstance(event.child(), QtWidgets.QWidget):
            event.child().installEventFilter(self)
            event.child().setStyle(self.parentWidget.style())
            for child in event.child().findChildren(QtWidgets.QWidget):
                child.installEventFilter(self)
                child.setStyle(self.parentWidget.style())
        elif event.type() == QtCore.QEvent.StyleChange and source == self.parentWidget:
            for child in self.parentWidget.findChildren(QtWidgets.QWidget):
                child.setStyle(self.parentWidget.style())
        return super().eventFilter(source, event)


class Demo(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        # this *must* be created before adding *any* child
        self.childEventWatcher = ChildEventWatcher(self)

        # ...
还要记住文档中警告的另一个重要方面:

警告:此功能对于演示用途特别有用,您需要展示Qt的样式功能。真正的应用程序应该避免它,而是使用一种一致的GUI样式


虽然上面的代码可以满足您的期望,但在所有子QWidget上安装事件过滤器并不是一件好事,特别是如果您只需要更改样式(通常只需更改一次,可能在程序开始时)。考虑到关于使用不同样式的警告,我强烈建议您完全按照建议执行此操作:仅出于演示目的,您可以在应用程序上设置它

from PyQt5 import QtWidgets, QtCore, QtGui
import sys


class Demo(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.container = QtWidgets.QWidget()
        self.setCentralWidget(self.container)
        self.layout = QtWidgets.QVBoxLayout()
        self.container.setLayout(self.layout)
        self.btn = QtWidgets.QPushButton("button")
        self.lw = QtWidgets.QListWidget()
        self.lw.addItems(["one", "two", "three"])
        self.layout.addWidget(self.btn)
        self.layout.addWidget(self.lw)
        self.resize(400, 150)
        self.show()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    win = Demo()
    
    app.setStyle(QtWidgets.QStyleFactory.create("Windows")) # Set style theme on app
    sys.exit(app.exec_())

这与OP想要的正好相反:在不同的小部件上使用不同的样式。