LCA-ActivityBrowser / activity-browser

GUI for brightway2
GNU Lesser General Public License v3.0
134 stars 50 forks source link

Add support for GIF tooltips #1150

Open marc-vdm opened 7 months ago

marc-vdm commented 7 months ago

Feature request

Standard pyqt tooltips don't support other content than text, but we can add support. This would mean we need to overwrite every class of things that have tooltips with our own subclass (e.g. ABPushButton instead of QPushbutton). We can then add a custom setGIFToolTip() function in addition to the setToolTip() for example.

The idea is that we can make much more useful in-UI guidance for users if we add video content in addition to the text tooltips that we currently have ("a picture is worth a thousand words", so GIFs should be able to explain quite a lot).

Some example code below we can probably adapt

class ToolTipAnimation(QtWidgets.QLabel):
    def __init__(self, parent, file, width=None, height=None):
        super().__init__(parent, flags=QtCore.Qt.ToolTip)
        self.setMouseTracking(True)
        self._file = file
        self._width = width
        self._height = height
        self._shown = False
        self.showTimer = QtCore.QTimer(interval=100, singleShot=True)
        QtWidgets.QApplication.instance().installEventFilter(self)

    def load(self):
        movie = QtGui.QMovie(self._file)
        if self._width and not self._height:
            self._height = self._width
        if self._width and self._height:
            size = QtCore.QSize(self._width, self._height)
            movie.setScaledSize(size)
        else:
            size = QtCore.QSize()
            for f in range(movie.frameCount()):
                movie.jumpToFrame(f)
                size = size.expandedTo(movie.currentImage().size())
            self.setFixedSize(size)
        self.setMovie(movie)
        self._shown = True

    def show(self, pos=None):
        if not self._shown:
            self.load()
        if pos is None:
            pos = QtGui.QCursor.pos()
        for screen in QtWidgets.QApplication.screens():
            if pos in screen.availableGeometry():
                screen = screen.availableGeometry()
                pos += QtCore.QPoint(2, 16)
                if pos.x() < screen.x():
                    pos.setX(screen.x())
                elif pos.x() + self.width() > screen.right():
                    pos.setX(screen.right() - self.width())
                if pos.y() < screen.y():
                    pos.setY(screen.y())
                elif pos.y() + self.height() > screen.bottom():
                    pos.setY(screen.bottom() - self.height())
                break
        self.move(pos)
        super().show()
        self.movie().start()

class ButtonWithGifTooltip(QPushButton):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.tooltip = ToolTipAnimation(self, 'path_to_your_gif.gif')

    def enterEvent(self, event):
        self.tooltip.show(self.mapToGlobal(self.rect().bottomRight()))

    def leaveEvent(self, event):
        self.tooltip.hide()

gif