tool_tip.py 3.2 KB
Newer Older
之一Yo's avatar
之一Yo 已提交
1
# coding:utf-8
之一Yo's avatar
之一Yo 已提交
2
from PyQt5.QtCore import QPropertyAnimation, QTimer, Qt, QPoint, QSize
之一Yo's avatar
之一Yo 已提交
3 4 5 6
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (QApplication, QFrame, QGraphicsDropShadowEffect,
                             QHBoxLayout, QLabel)

之一Yo's avatar
之一Yo 已提交
7 8
from ...common import setStyleSheet

之一Yo's avatar
之一Yo 已提交
9 10

class ToolTip(QFrame):
之一Yo's avatar
之一Yo 已提交
11
    """ Tool tip """
之一Yo's avatar
之一Yo 已提交
12 13 14 15 16

    def __init__(self, text='', parent=None):
        super().__init__(parent=parent)
        self.__text = text
        self.__duration = 1000
之一Yo's avatar
之一Yo 已提交
17
        self.container = QFrame(self)
之一Yo's avatar
之一Yo 已提交
18
        self.timer = QTimer(self)
之一Yo's avatar
之一Yo 已提交
19 20 21

        self.setLayout(QHBoxLayout())
        self.containerLayout = QHBoxLayout(self.container)
之一Yo's avatar
之一Yo 已提交
22 23 24 25
        self.label = QLabel(text, self)
        self.ani = QPropertyAnimation(self, b'windowOpacity', self)

        # set layout
之一Yo's avatar
之一Yo 已提交
26 27 28 29
        self.layout().setContentsMargins(15, 10, 15, 15)
        self.layout().addWidget(self.container)
        self.containerLayout.addWidget(self.label)
        self.containerLayout.setContentsMargins(10, 7, 10, 7)
之一Yo's avatar
之一Yo 已提交
30 31 32

        # add shadow
        self.shadowEffect = QGraphicsDropShadowEffect(self)
之一Yo's avatar
之一Yo 已提交
33
        self.shadowEffect.setBlurRadius(25)
之一Yo's avatar
之一Yo 已提交
34 35
        self.shadowEffect.setColor(QColor(0, 0, 0, 60))
        self.shadowEffect.setOffset(0, 5)
之一Yo's avatar
之一Yo 已提交
36
        self.container.setGraphicsEffect(self.shadowEffect)
之一Yo's avatar
之一Yo 已提交
37 38 39 40 41

        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.hide)

        # set style
之一Yo's avatar
之一Yo 已提交
42 43
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint)
之一Yo's avatar
之一Yo 已提交
44 45 46 47 48 49 50 51 52 53
        self.setDarkTheme(False)
        self.__setQss()

    def text(self):
        return self.__text

    def setText(self, text: str):
        """ set text on tooltip """
        self.__text = text
        self.label.setText(text)
之一Yo's avatar
之一Yo 已提交
54
        self.container.adjustSize()
之一Yo's avatar
之一Yo 已提交
55 56 57 58 59 60 61 62 63 64 65
        self.adjustSize()

    def duration(self):
        return self.__duration

    def setDuration(self, duration: int):
        """ set tooltip duration in milliseconds """
        self.__duration = abs(duration)

    def __setQss(self):
        """ set style sheet """
之一Yo's avatar
之一Yo 已提交
66 67 68
        self.container.setObjectName("container")
        self.label.setObjectName("contentLabel")
        setStyleSheet(self, 'tool_tip')
之一Yo's avatar
之一Yo 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
        self.label.adjustSize()
        self.adjustSize()

    def setDarkTheme(self, dark=False):
        """ set dark theme """
        self.setProperty('dark', dark)
        self.setStyle(QApplication.style())

    def showEvent(self, e):
        self.timer.stop()
        self.timer.start(self.__duration)
        super().showEvent(e)

    def hideEvent(self, e):
        self.timer.stop()
之一Yo's avatar
之一Yo 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        super().hideEvent(e)

    def adjustPos(self, pos: QPoint, size: QSize):
        """ adjust the position of tooltip relative to widget

        Parameters
        ----------
        pos: QPoint
            global position of widget

        size: QSize
            size of widget
        """
        x = pos.x() + size.width()//2 - self.width()//2
        y = pos.y() - self.height()

        # adjust postion to prevent tooltips from appearing outside the screen
        desk = QApplication.desktop()
        x = min(max(0, x), desk.width() - self.width() - 5)
        y = min(max(0, y), desk.height() - self.height() - 5)

        self.move(x, y)