如何禁用样式表中的焦点指示器
How to dissable the focus indication in stylesheet
当我的 QDoubleSpinBox 获得焦点时,它会得到一个蓝色轮廓(以“Fusion”样式):
如何关闭此功能?
仅使用样式表来做到这一点 可行,但有一个重要的缺点:为 QSpinBox 等复杂小部件设置样式 需要 才能正确设置 所有子控件属性。
基本解决方案是为小部件设置边框:
QSpinBox {
border: 1px inset palette(mid);
border-radius: 2px;
}
请记住,提供适当的焦点可见响应确实重要;您可能不喜欢 Fusion 样式提供的“发光”(和颜色),但是无论小部件是否具有焦点,它都应该始终可见,即使它具有闪烁的文本光标。您可以通过使用 :focus
选择器指定稍微不同的颜色来做到这一点:
QSpinBox:focus {
border: 1px inset palette(dark);
}
不幸的是,正如开头所解释的,这有一个重要的缺点:一旦应用了样式表,小部件绘制就会回到基本的原始方法(右边的旋转框使用上面的样式表):
不幸的是,几乎没有直接的方法来恢复箭头的默认绘制,因为使用样式表会阻止这种情况。因此,唯一的解决方案是提供控件的属性,如 examples about customizing QSpinBox.
中所述
不过,还有一个替代方案,即使用 QProxyStyle. The trick is to intercept the control in the drawComplexControl()
实现并在调用默认实现之前删除该选项的 State_HasFocus
标志。
在下面的示例中,我还检查了焦点 before 移除标志以提供足够的视觉反馈,并且我还移除了悬停时显示发光效果的 State_MouseOver
标志.
class Proxy(QtWidgets.QProxyStyle):
def drawComplexControl(self, cc, opt, qp, widget=None):
if cc == self.CC_SpinBox:
opt = QtWidgets.QStyleOptionSpinBox(opt)
if opt.state & self.State_HasFocus:
opt.palette.setColor(QtGui.QPalette.Window,
opt.palette.color(QtGui.QPalette.Window).darker(100))
else:
opt.palette.setColor(QtGui.QPalette.Window,
opt.palette.color(QtGui.QPalette.Window).lighter(125))
opt.state &= ~(self.State_HasFocus | self.State_MouseOver)
super().drawComplexControl(cc, opt, qp, widget)
# ...
app = QtWidgets.QApplication(sys.argv)
app.setStyle(Proxy())
# ...
请注意,上述“颜色校正”仅适用于 Fusion 样式和其他使用 Window
调色板角色绘制边框的样式。例如,Windows
样式根本不考虑它,或者您可能希望使用更高的 darker()
或 lighter()
值以提供更好的区分。
当我的 QDoubleSpinBox 获得焦点时,它会得到一个蓝色轮廓(以“Fusion”样式):
如何关闭此功能?
仅使用样式表来做到这一点 可行,但有一个重要的缺点:为 QSpinBox 等复杂小部件设置样式 需要 才能正确设置 所有子控件属性。
基本解决方案是为小部件设置边框:
QSpinBox {
border: 1px inset palette(mid);
border-radius: 2px;
}
请记住,提供适当的焦点可见响应确实重要;您可能不喜欢 Fusion 样式提供的“发光”(和颜色),但是无论小部件是否具有焦点,它都应该始终可见,即使它具有闪烁的文本光标。您可以通过使用 :focus
选择器指定稍微不同的颜色来做到这一点:
QSpinBox:focus {
border: 1px inset palette(dark);
}
不幸的是,正如开头所解释的,这有一个重要的缺点:一旦应用了样式表,小部件绘制就会回到基本的原始方法(右边的旋转框使用上面的样式表):
不幸的是,几乎没有直接的方法来恢复箭头的默认绘制,因为使用样式表会阻止这种情况。因此,唯一的解决方案是提供控件的属性,如 examples about customizing QSpinBox.
中所述不过,还有一个替代方案,即使用 QProxyStyle. The trick is to intercept the control in the drawComplexControl()
实现并在调用默认实现之前删除该选项的 State_HasFocus
标志。
在下面的示例中,我还检查了焦点 before 移除标志以提供足够的视觉反馈,并且我还移除了悬停时显示发光效果的 State_MouseOver
标志.
class Proxy(QtWidgets.QProxyStyle):
def drawComplexControl(self, cc, opt, qp, widget=None):
if cc == self.CC_SpinBox:
opt = QtWidgets.QStyleOptionSpinBox(opt)
if opt.state & self.State_HasFocus:
opt.palette.setColor(QtGui.QPalette.Window,
opt.palette.color(QtGui.QPalette.Window).darker(100))
else:
opt.palette.setColor(QtGui.QPalette.Window,
opt.palette.color(QtGui.QPalette.Window).lighter(125))
opt.state &= ~(self.State_HasFocus | self.State_MouseOver)
super().drawComplexControl(cc, opt, qp, widget)
# ...
app = QtWidgets.QApplication(sys.argv)
app.setStyle(Proxy())
# ...
请注意,上述“颜色校正”仅适用于 Fusion 样式和其他使用 Window
调色板角色绘制边框的样式。例如,Windows
样式根本不考虑它,或者您可能希望使用更高的 darker()
或 lighter()
值以提供更好的区分。