Есть ли способ создать собственный анимированный / gif QCursor? - PullRequest
3 голосов
/ 01 апреля 2019

Я пытаюсь создать анимированный курсор custum, который заменяет обычный курсор, когда длительные процессы происходят, как здесь и здесь , однако, я бы хотел, чтобы мой быланимированные, например, с помощью GIF, так же, как это имеет место со стандартом Qt.WaitCursor.Как я могу это сделать?Я нашел это решение, касающееся анимированных значков на панели задач, однако мне не удалось адаптировать его для работы со значком курсора.

В качестве примечания: при попыткевыполнить pm.setAlphaChannel(bm), как указано в первой ссылке, это не работает для меня, и я получаю следующую ошибку:

'AttributeError: QPixmap' object has no attribute 'setAlphaChannel'

Что странно, потому что согласно документации , QPixmap имеетsetAlphaChannel метод.

1 Ответ

3 голосов
/ 01 апреля 2019

Одним из возможных решений является создание класса, который обрабатывает обновление курсора данного виджета.В следующем примере курсор устанавливается при нажатии кнопки запуска и курсор восстанавливается при нажатии кнопки остановки:

from PyQt5 import QtCore, QtGui, QtWidgets

class ManagerCursor(QtCore.QObject):
    def __init__(self, parent=None):
        super(ManagerCursor, self).__init__(parent)
        self._movie = None
        self._widget = None
        self._last_cursor = None

    def setMovie(self, movie):
        if isinstance(self._movie, QtGui.QMovie):
            if not self._movie != QtGui.QMovie.NotRunning:
                self._movie.stop()
            del self._movie
        self._movie = movie
        self._movie.frameChanged.connect(self.on_frameChanged)
        self._movie.started.connect(self.on_started)
        self._movie.finished.connect(self.restore_cursor)

    def setWidget(self, widget):
        self._widget = widget

    @QtCore.pyqtSlot()
    def on_started(self):
        if self._widget is not None:
            self._last_cursor = self._widget.cursor()

    @QtCore.pyqtSlot()
    def restore_cursor(self):
        if self._widget is not None:
            if self._last_cursor is not None:
                self._widget.setCursor(self._last_cursor)
        self._last_cursor = None

    @QtCore.pyqtSlot()
    def start(self):
        if self._movie is not None:
            self._movie.start()

    @QtCore.pyqtSlot()
    def stop(self):
        if self._movie is not None:
            self._movie.stop()
            self.restore_cursor()

    @QtCore.pyqtSlot()
    def on_frameChanged(self):
        pixmap = self._movie.currentPixmap()
        cursor = QtGui.QCursor(pixmap)
        if self._widget is not None:
            if self._last_cursor is None:
                self._last_cursor = self._widget.cursor()
            self._widget.setCursor(cursor)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        start_btn = QtWidgets.QPushButton("start", clicked=self.on_start)
        stop_btn = QtWidgets.QPushButton("stop", clicked=self.on_stop)

        self._manager = ManagerCursor(self)
        movie = QtGui.QMovie("loading-icon.gif")
        self._manager.setMovie(movie)
        self._manager.setWidget(self)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(start_btn)
        lay.addWidget(stop_btn)
        lay.addStretch()

    @QtCore.pyqtSlot()
    def on_start(self):
        self._manager.start()

    @QtCore.pyqtSlot()
    def on_stop(self):
        self._manager.stop()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...