
Изначально я устанавливал растровую маску, и у меня возникла та же проблема. Именно тогда я понял, что это лучше. Я сам рисую фигуру на полупрозрачном окне из-за сглаживания, которое оно включает в себя, но, как видите, все равно безуспешно.
Я не уверен, делаю ли я что-то не так или это потому, что форма слишком мала? Если масштаб был проблемой, это должно было быть заметно по кнопке и тексту, которые кажутся гладкими.
import typing as _t
# You might need to change this import to PySide2/PyQt5 depending on what you have.
from Qt import (
QtCore as _QtCore,
QtGui as _QtGui,
QtWidgets as _QtWidgets,
)
class _TipTriangleDimensions(_t.NamedTuple):
height: int = 15
base: int = 10
class _TipTriangleCords(_t.NamedTuple):
origin: _QtCore.QPoint
tip: _QtCore.QPoint
base: _QtCore.QPoint
class QBalloonTip(_QtWidgets.QWidget):
def __init__(
self, message: str, parent: _t.Optional[_QtWidgets.QWidget] = None
) -> None:
super().__init__(
parent=parent,
f=_QtCore.Qt.FramelessWindowHint | _QtCore.Qt.WindowSystemMenuHint,
)
self.setAttribute(_QtCore.Qt.WA_TranslucentBackground)
main_layout = _QtWidgets.QVBoxLayout()
self._setup_ui(main_layout)
self._message_label.setText(message)
self._mask_region: _QtGui.QRegion = self._get_mask_region(
_TipTriangleDimensions()
)
def paintEvent(self, event):
painter = _QtGui.QPainter(self)
painter.setRenderHint(_QtGui.QPainter.RenderHint.Antialiasing)
painter_path = _QtGui.QPainterPath()
painter_path.addRegion(self._mask_region)
brush = _QtGui.QBrush(_QtCore.Qt.white)
painter.fillPath(painter_path, brush)
def _get_mask_region(self, triangle_d: _TipTriangleDimensions) -> _QtGui.QRegion:
self.setContentsMargins(0, 0, 0, triangle_d.height)
self.updateGeometry()
self_sz: _QtCore.QSize = self.sizeHint()
triangle_cords = self._get_triangle_shape_points(self_sz, triangle_d)
origin = _QtCore.QPoint(0, 0)
right = _QtCore.QPoint(self_sz.width(), triangle_cords.base.y())
top = _QtCore.QPoint(self_sz.width(), origin.y())
return _QtGui.QRegion(
[
origin,
triangle_cords.tip,
triangle_cords.base,
right,
top,
origin,
]
)
@staticmethod
def _get_triangle_shape_points(
total_size: _QtCore.QSize, dimensions: _TipTriangleDimensions
) -> _TipTriangleCords:
origin = _QtCore.QPoint(0, total_size.height() - dimensions.height)
tip = _QtCore.QPoint(0, total_size.height())
base = _QtCore.QPoint(dimensions.base, origin.y())
return _TipTriangleCords(origin, tip, base)
def _setup_ui(self, main_layout: _QtWidgets.QVBoxLayout):
self._message_label = _QtWidgets.QLabel(parent=self)
self._message_label.setFixedWidth(200)
self._message_label.setFixedHeight(100)
self._message_label.setWordWrap(True)
main_layout.addWidget(self._message_label)
main_layout.addWidget(_QtWidgets.QPushButton("Test"))
self.setLayout(main_layout)
if __name__ == "__main__":
app = _QtWidgets.QApplication([])
widget = QBalloonTip("test message")
widget.show()
app.exec_()
Подробнее здесь: https://stackoverflow.com/questions/792 ... get-window