如何在pyqt5中使Qtooltip圆角。尝试了许多样式表,但都不起作用。Qtooltip上的框架保持不变。
Qt样式表无法设置小部件的掩码,这是将顶级小部件的形状更改为与标准矩形不同的形状所必需的。
虽然这个问题有部分答案,但它已经很老了,并且没有解释如何正确使用样式提示和实现样式。
该解决方案基于QProxyStyle,它通过根据内容创建适当的掩码来更新styleHint()
的returnData。
这里最大的问题是,绝对没有办法知道小部件使用的QSS属性(访问小部件的styleSheet()
是毫无意义的,因为样式表可以继承(:我们永远无法知道小部件是否有边界,以及边界的可能半径。
不过,有一种方法:我们可以在QImage上本地呈现工具提示,并使用createHeuristicMask()
根据内容获取可能的掩码,该掩码应该使用应用程序样式表进行设置。
如果由于某种原因,掩码仍然是小部件的完整矩形,我们可以"猜测;一个标准的圆形面具。
注意,styleHint()
的returnData
是QStyleHintReturn,而我们需要QStyleHindReturnMask,因为我们必须能够编写它的region
;为了实现这一点,我们使用了sip
模块的cast()
功能(通常与PyQt一起安装(。
以下使用工具提示样式表的默认调色板颜色,但重要的一点是边框必须与背景略有不同(否则上述遮罩创建将无法工作(。
from PyQt5 import QtCore, QtGui, QtWidgets
import sip
class ProxyStyle(QtWidgets.QProxyStyle):
def styleHint(self, hint, opt=None, widget=None, returnData=None):
if hint == self.SH_ToolTip_Mask and widget:
if super().styleHint(hint, opt, widget, returnData):
# the style already creates a mask
return True
returnData = sip.cast(returnData, QtWidgets.QStyleHintReturnMask)
src = QtGui.QImage(widget.size(), QtGui.QImage.Format_ARGB32)
src.fill(QtCore.Qt.transparent)
widget.render(src)
mask = QtGui.QRegion(QtGui.QBitmap.fromImage(
src.createHeuristicMask()))
if mask == QtGui.QRegion(opt.rect.adjusted(1, 1, -1, -1)):
# if the stylesheet doesn't set a border radius, create one
x, y, w, h = opt.rect.getRect()
mask = QtGui.QRegion(x + 4, y, w - 8, h)
mask += QtGui.QRegion(x, y + 4, w, h - 8)
mask += QtGui.QRegion(x + 2, y + 1, w - 4, h - 2)
mask += QtGui.QRegion(x + 1, y + 2, w - 2, h - 4)
returnData.region = mask
return 1
return super().styleHint(hint, opt, widget, returnData)
app = QtWidgets.QApplication([])
app.setStyle(ProxyStyle())
palette = app.palette()
app.setStyleSheet('''
QToolTip {{
color: {fgd};
background: {bgd};
border: 1px solid {border};
border-radius: 4px;
}}
'''.format(
fgd=palette.color(palette.ToolTipText).name(),
bgd=palette.color(palette.ToolTipBase).name(),
border=palette.color(palette.ToolTipBase).darker(110).name()
))
test = QtWidgets.QPushButton('Hover me', toolTip='Tool tip')
test.show()
app.exec()
不过,请注意,这并不是最理想的,因为它涉及到每次显示/调整工具提示的大小时都要渲染工具提示:如果程序显示许多工具提示或频繁更新它们,则性能可能会变差。另一种选择是完全跳过启发式掩码创建,只根据内容设置一个预定义的默认掩码,如上面styleHint()
覆盖结束时所示。