有没有办法改变所有 QMessageBox 的 OK 按钮的样式表?
Is there a way to change the stylesheet of just OK button of all the QMessageBox?
我想让我的 GUI 中所有 QMessageBox
的确定按钮(这很复杂,所以有很多)相对于其他按钮设置不同的颜色(取消, 没有等等).
我不想每次创建新的时候都设置它的颜色QMessageBox
,但我想通过我的应用程序的样式表一劳永逸地设置它。
我尝试了不同的选项,但 none 个选项有效:
- QMessageBox#okButton {background-color:blue}
- QMessageBox::okButton {...}
- QMessageBox:okButton {...}
- QMessageBox#ok-button {...}
- QMessageBox QPushButton#okButton {...}
和其他人...
有什么办法还是必须放弃?
一个可能的解决方案是将 objectName()
设置为每个按钮的选择器,为此您可以使用 QApplication
:
的 notify()
方法
from PySide2.QtCore import QEvent
from PySide2.QtWidgets import *
class Application(QApplication):
def notify(self, receiver, event):
if isinstance(receiver, QMessageBox) and event.type() == QEvent.Show:
for button in receiver.buttons():
sb = receiver.standardButton(button)
if not button.objectName():
button.setObjectName(sb.name.decode())
button.style().unpolish(button)
button.style().polish(button)
return super().notify(receiver, event)
def main():
app = Application()
app.setStyle("fusion")
app.setStyleSheet(
"""
QPushButton#Ok { background-color: green }
QPushButton#Cancel { background-color: red }
"""
)
QMessageBox.critical(
None, "Title", "text", buttons=QMessageBox.Ok | QMessageBox.Cancel
)
msgBox = QMessageBox()
msgBox.setText("The document has been modified.")
msgBox.setInformativeText("Do you want to save your changes?")
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msgBox.exec_()
if __name__ == "__main__":
main()
不幸的是,没有直接的解决方案,因为 QDialogButtonBox(这是 QMessageBox 用于其按钮的)不提供按钮角色的选择器。
对于静态创建的消息框,唯一的方法是使用 [text="button text"]
选择器,但这只是一个猜测,可能会根据本地化和样式(可以设置助记符,和您甚至无法确定那是什么)。此外,这需要为 QApplication 设置样式表。
适用于这些情况的可能的应用程序范围样式表如下所示:
app.setStyleSheet('''
QDialogButtonBox > QPushButton[text="&OK"] {
background-color: orange;
}
QDialogButtonBox > QPushButton[text="&Cancel"] {
background-color: green;
}
''')
请注意,我使用了 Parent > Class
选择器以确保只有 QDialogButtonBox 的按钮具有这些规则的样式,否则 any “确定”按钮将是橙色的等
尽管如此,在我的计算机上的上述情况下,它仅适用于“确定”按钮,因为我的本地化(意大利语)对另一个使用“&Annulla”。
另一方面,如果您要创建 QMessageBox 实例,则使用基于对象名称的选择器会更加自由和灵活。
唯一的问题是,由于对象名称是在创建后设置的,因此未应用样式表,因此按钮在实例化后必须“未抛光”。
一个简单的子类可以提供一个标准的接口,而不会使事情过于复杂:
class ColoredMessageBox(QtWidgets.QMessageBox):
StandardNames = {
QtWidgets.QMessageBox.Ok: 'Ok',
QtWidgets.QMessageBox.Cancel: 'Cancel',
QtWidgets.QMessageBox.Save: 'Save',
# ...
}
def exec_(self):
for button in self.buttons():
objName = self.StandardNames.get(self.standardButton(button))
if objName:
button.setObjectName(objName)
self.style().unpolish(button)
return super().exec_()
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet('''
QMessageBox > QDialogButtonBox > QPushButton#Ok {
background-color: orange;
}
QMessageBox > QDialogButtonBox > QPushButton#Cancel {
background-color: blue;
}
''')
w = ColoredMessageBox(QtWidgets.QMessageBox.Information, 'Hello', 'How are you?',
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
w.exec_()
我想让我的 GUI 中所有 QMessageBox
的确定按钮(这很复杂,所以有很多)相对于其他按钮设置不同的颜色(取消, 没有等等).
我不想每次创建新的时候都设置它的颜色QMessageBox
,但我想通过我的应用程序的样式表一劳永逸地设置它。
我尝试了不同的选项,但 none 个选项有效:
- QMessageBox#okButton {background-color:blue}
- QMessageBox::okButton {...}
- QMessageBox:okButton {...}
- QMessageBox#ok-button {...}
- QMessageBox QPushButton#okButton {...}
和其他人...
有什么办法还是必须放弃?
一个可能的解决方案是将 objectName()
设置为每个按钮的选择器,为此您可以使用 QApplication
:
notify()
方法
from PySide2.QtCore import QEvent
from PySide2.QtWidgets import *
class Application(QApplication):
def notify(self, receiver, event):
if isinstance(receiver, QMessageBox) and event.type() == QEvent.Show:
for button in receiver.buttons():
sb = receiver.standardButton(button)
if not button.objectName():
button.setObjectName(sb.name.decode())
button.style().unpolish(button)
button.style().polish(button)
return super().notify(receiver, event)
def main():
app = Application()
app.setStyle("fusion")
app.setStyleSheet(
"""
QPushButton#Ok { background-color: green }
QPushButton#Cancel { background-color: red }
"""
)
QMessageBox.critical(
None, "Title", "text", buttons=QMessageBox.Ok | QMessageBox.Cancel
)
msgBox = QMessageBox()
msgBox.setText("The document has been modified.")
msgBox.setInformativeText("Do you want to save your changes?")
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msgBox.exec_()
if __name__ == "__main__":
main()
不幸的是,没有直接的解决方案,因为 QDialogButtonBox(这是 QMessageBox 用于其按钮的)不提供按钮角色的选择器。
对于静态创建的消息框,唯一的方法是使用 [text="button text"]
选择器,但这只是一个猜测,可能会根据本地化和样式(可以设置助记符,和您甚至无法确定那是什么)。此外,这需要为 QApplication 设置样式表。
适用于这些情况的可能的应用程序范围样式表如下所示:
app.setStyleSheet('''
QDialogButtonBox > QPushButton[text="&OK"] {
background-color: orange;
}
QDialogButtonBox > QPushButton[text="&Cancel"] {
background-color: green;
}
''')
请注意,我使用了 Parent > Class
选择器以确保只有 QDialogButtonBox 的按钮具有这些规则的样式,否则 any “确定”按钮将是橙色的等
尽管如此,在我的计算机上的上述情况下,它仅适用于“确定”按钮,因为我的本地化(意大利语)对另一个使用“&Annulla”。
另一方面,如果您要创建 QMessageBox 实例,则使用基于对象名称的选择器会更加自由和灵活。
唯一的问题是,由于对象名称是在创建后设置的,因此未应用样式表,因此按钮在实例化后必须“未抛光”。
一个简单的子类可以提供一个标准的接口,而不会使事情过于复杂:
class ColoredMessageBox(QtWidgets.QMessageBox):
StandardNames = {
QtWidgets.QMessageBox.Ok: 'Ok',
QtWidgets.QMessageBox.Cancel: 'Cancel',
QtWidgets.QMessageBox.Save: 'Save',
# ...
}
def exec_(self):
for button in self.buttons():
objName = self.StandardNames.get(self.standardButton(button))
if objName:
button.setObjectName(objName)
self.style().unpolish(button)
return super().exec_()
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet('''
QMessageBox > QDialogButtonBox > QPushButton#Ok {
background-color: orange;
}
QMessageBox > QDialogButtonBox > QPushButton#Cancel {
background-color: blue;
}
''')
w = ColoredMessageBox(QtWidgets.QMessageBox.Information, 'Hello', 'How are you?',
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
w.exec_()