«Мигающие» кнопки в PyQT5 - PullRequest
0 голосов
/ 06 июня 2018

Вот в чем дело: я пытаюсь заставить кнопку A мигать при нажатии кнопки B, и мигание должно прекратиться, когда пользователь нажимает кнопку A. Кроме того, кнопка A должна затем вернуться в свое прежнее состояние.

После долгого чтения документации и других вопросов в SO, у меня теперь есть следующий фрагмент кода:

Python 2.7

class Widget(QWidget):

    def __init__(self):
        super(Widget, self).__init__()

        self.resize(300,200)
        layout = QVBoxLayout(self)


        self.button_stop = QPushButton("Stop")
        layout.addWidget(self.button_stop)

        self.button_start = QPushButton("Start", self)
        layout.addWidget(self.button_start)

        self.animation = QPropertyAnimation(self, "color", self)
        self.animation.setDuration(1000)
        self.animation.setLoopCount(100)
        self.animation.setStartValue(self.color)
        self.animation.setEndValue(self.color)
        self.animation.setKeyValueAt(0.1, QColor(0,255,0))

        self.button_start.clicked.connect(self.animation.start)
        self.button_stop.clicked.connect(lambda: self.stop())

    def stop(self):
        self.animation.stop()
        self.button_stop.setStyleSheet("")

    def getColor(self):
        return self.button_stop.palette().base()

    def setColor(self, color):
        palette = self.button_stop.palette()
        palette.setColor(self.button_stop.backgroundRole(), color)
        self.button_stop.setAutoFillBackground(True)
        self.button_stop.setPalette(palette)


    color = pyqtProperty(QColor, getColor, setColor)


if __name__ == "__main__":
    app = QApplication([])
    w = Widget()
    w.show()
    app.exec_()

сам код я получил в основном от @Alexander Lutsenko в этом вопросе, с некоторыми изменениями тут и там, чтобы проверить мои потребности.Основная часть проста: я создаю окно с двумя QPushButton, одно для запуска QPropertyAnimation и другое для его остановки.Сам QPropertyAnimation применяется к одной из кнопок.Теоретически он должен изменить цвет фона кнопки, но из-за ограничений, описанных в , этот другой вопрос обеспечивает только красочную рамку для QPushButton.И я в порядке с этим, это не выглядит так навязчиво.

Проблема

После запуска анимации, если я нажму кнопку Stop,кнопка не возвращается в исходное состояние (без цветной рамки), но остается с цветом анимации во время нажатия кнопки Stop.

Кроме того, я получаю следующее предупреждение:

TypeError: unable to convert a Python 'QBrush' object to a C++ 'QColor' instance

Но скрипт продолжает работать и анимация продолжается, так что ничего не ломается.

Вопрос

Как правильно "сбросить" таблицу стилей кнопки?Есть ли другой (может быть, лучший и питонный) способ сделать мигающую кнопку?Большое спасибо!

1 Ответ

0 голосов
/ 06 июня 2018

Свойство не сохраняет начальное состояние, поэтому даже если вы создадите пару анимации, оно не будет восстановлено до исходного состояния.Таким образом, решение в этом случае состоит в том, чтобы сохранить это состояние в переменной и создать метод reset_color(), который снова восстанавливает цвет.

С другой стороны, сообщение об ошибке: TypeError: unable to convert to Python 'QBrush' object to a C ++ 'QColor' instance указывает, что код self.button_stop.palette().base() возвращает QBrush, но ожидается QColor, и преобразование не подразумевается, поэтому реализация должна быть изменена.

По порядку я создам новый класс, который наследуетиз QPushButton и реализуйте эти свойства.

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class BlinkButton(QPushButton):
    def __init__(self, *args, **kwargs):
        QPushButton.__init__(self, *args, **kwargs)
        self.default_color = self.getColor()

    def getColor(self):
        return self.palette().color(QPalette.Button)

    def setColor(self, value):
        if value == self.getColor():
            return
        palette = self.palette()
        palette.setColor(self.backgroundRole(), value)
        self.setAutoFillBackground(True)
        self.setPalette(palette)

    def reset_color(self):
        self.setColor(self.default_color)

    color = pyqtProperty(QColor, getColor, setColor)


class Widget(QWidget):

    def __init__(self):
        super(Widget, self).__init__()

        self.resize(300,200)
        layout = QVBoxLayout(self)

        self.button_stop = BlinkButton("Stop")
        layout.addWidget(self.button_stop)

        self.button_start = QPushButton("Start", self)
        layout.addWidget(self.button_start)

        self.animation = QPropertyAnimation(self.button_stop, "color", self)
        self.animation.setDuration(1000)
        self.animation.setLoopCount(100)
        self.animation.setStartValue(self.button_stop.default_color)
        self.animation.setEndValue(self.button_stop.default_color)
        self.animation.setKeyValueAt(0.1, QColor(0,255,0))

        self.button_start.clicked.connect(self.animation.start)
        self.button_stop.clicked.connect(self.stop)

    def stop(self):
        self.animation.stop()
        self.button_stop.reset_color()

if __name__ == "__main__":
    app = QApplication([])
    w = Widget()
    w.show()
    app.exec_()
...