macOS下PySide2的QPushButton样式随字体变化如何修复?
问题成因
这个问题是Qt macOS平台原生样式的内部渲染逻辑导致的:
Qt在macOS上使用QMacStyle原生系统样式绘制控件时,对QPushButton的渲染有特殊逻辑:只要检测到QPushButton被应用了任何样式表规则,就会自动放弃调用系统原生控件绘制接口,转而使用Qt自身的通用控件绘制逻辑渲染按钮。你使用*通配符设置全局字体样式表时,相当于给所有控件包括QPushButton都应用了样式表规则,因此触发了这个 fallback 逻辑,才会出现你看到的按钮边框、圆角等样式和原生按钮不一致的情况。
其他控件没有出现这个问题,是因为它们的原生绘制逻辑对样式表的敏感度更低,仅设置字体的样式表规则不会让它们放弃原生渲染路径,所以样式不会发生变化。
解决方案
方案一:使用QApplication.setFont设置全局字体(最简便)
不要用全局通配符样式表设置字体,改用Qt原生的全局字体设置接口,这个方法不会给控件应用样式表,因此不会触发QPushButton的 fallback 逻辑,可以同时实现全局字体修改和保留按钮原生样式。
你可以把示例代码中的信号槽关联逻辑修改为:
fonts.currentIndexChanged.connect(lambda i: QtWidgets.QApplication.instance().setFont(QtGui.QFont(fonts.itemText(i))))
删除原有的样式表设置代码即可。
方案二:样式表排除QPushButton
如果你必须使用样式表设置字体,可以在样式表中排除QPushButton控件,让按钮保留默认的系统样式,单独给其他控件设置字体:
QWidget:not(QPushButton) { font-family: "{fonts.itemText(i)}"; }
如果后续发现其他控件也有类似问题,也可以加到排除列表中。
方案三:模拟原生按钮样式
如果需要给QPushButton也更换字体同时保留原生样式,可以手动给QPushButton写固定样式表,模拟macOS原生按钮的外观,匹配系统明暗模式对应的样式参数即可。
内容的提问来源于stack exchange,提问作者Programus
相关产品推荐
相关产品推荐

