Question: I need to properly display a tooltip with rounded corners using PyQt5. The default behavior whenever using the border-radius: 8px; in the stylesheet of a QToolTip keeps the tooltip rendered as a rectangle, and the border-radius property only impacts the shape of the border, which is rather ugly. This question is following this question : How to make Qtooltip corner round in pyqt5 which was left partially unanswered. Based on this answer, I tried this code : 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: black; background: white; border: 1px solid black; border-radius: 8px; } ''') test = QtWidgets.QPushButton('Hover me', toolTip='Tool tip') test.show() app.exec()  However this does not work as expected :  the produced tooltip does not change from the default one. After some debugging, I noticed that sizeHint() logic is actually never executed ; super().styleHint(hint, opt, widget, returnData) always returns True. How can I render a tooltip with rounded corners ? Edit : I am running Windows 11, and it seems that it is important (see answer)

Answer: It seems that by default, Windows 11 creates a mask for tooltips ; therefore if super().styleHint(hint, opt, widget, returnData): is always True. If we want to run the logic generating the mask, we have to remove that block. In order to render the tooltip, to get a mask to clip it later, we also have to prevent infinite recursion ; widget.render would call this styleHint which would in turn call widget.render. Therefore we have to add a recursive check. Lastly, due to the antialiased pixels of the border, the produced mask is a tiny bit too large. To fix that issue, we have to crop the mask of 1px in every direction, which can be done by downscaling the mask by 2 pixels in both directions and then translate the QRegion by 1px. Here is a working code (at least on Windows 11, with PyQt5): class ProxyStyle(QtWidgets.QProxyStyle): _recursive_check = False def styleHint(self, hint, opt=None, widget=None, returnData=None): if hint == self.SH_ToolTip_Mask and widget and not self._recursive_check: self._recursive_check = True returnData = sip.cast(returnData, QtWidgets.QStyleHintReturnMask) src = QtGui.QImage(widget.size(), QtGui.QImage.Format_ARGB32) src.fill(QtCore.Qt.transparent) widget.render(src) image = src.createHeuristicMask() bitmap = QtGui.QBitmap.fromImage(image) mask = QtGui.QRegion(bitmap) x, y, w, h = opt.rect.getRect() if mask == QtGui.QRegion(opt.rect.adjusted(1, 1, -1, -1)): 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) image = image.scaled(image.width()-2, image.height()-2) bitmap = QtGui.QBitmap.fromImage(image) mask = QtGui.QRegion(bitmap).translated(1, 1) returnData.region = mask self._recursive_check = False return 1 return super().styleHint(hint, option=opt, widget=widget, returnData=returnData) app = QtWidgets.QApplication([]) app.setStyle(ProxyStyle()) palette = app.palette() app.setStyleSheet(''' QToolTip {{ color: {fgd}; background: {bgd}; border: 2px solid black; border-radius: 13px; }} '''.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()