Анимация кнопок работает неправильно
Пытаясь создать анимированные кнопки при наведении в активном окне, воспользовался подсказкой из этого вопроса.
Использовал конструкцию условия чтобы определить какая кнопка, какую анимацию должна проигрывать, но вместо ожидаемого, получил результат, при котором анимацию проигрывает только средняя кнопка.
А если быстро провести курсором по кнопкам, то анимация и вовсе пропадает и появляется лишь тогда, когда окно перезапущено.
Таким образом вырисовывается две проблемы:
- Анимация проигрывается только на средней кнопке, остальные лишь тригерят проигрывание анимации на средней кнопке.
- Анимация ломается и больше не воспроизводится если по всему ряду кнопок провести курсором не останавливаясь.
import sys
import os
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.resize(310, 105)
self.angle = 0
self.val = 0
self.i = 0
# min_button
self.image_fname_min_button = ('icons/cil-minus.png')
self.min_button = QPushButton(self)
self.min_button.resize(100, 100)
self.min_button.setIcon(
QIcon(QPixmap(self.image_fname_min_button)))
# Animation min_button
self.min_button.installEventFilter(self)
self.timer_min_button = QtCore.QTimer()
self.timer_min_button.timeout.connect(
lambda: self.onRotate('min_button', self.val))
# max_button
self.image_fname_max_button = ('icons/cil-fullscreen.png')
self.max_button = QPushButton(self)
self.max_button.move(105, 0)
self.max_button.resize(100, 100)
self.max_button.setIcon(
QIcon(QPixmap(self.image_fname_max_button)))
# Animation max_button
self.max_button.installEventFilter(self)
self.timer_max_button = QtCore.QTimer()
self.timer_max_button.timeout.connect(
lambda: self.onRotate('max_button', self.val))
# close_button
self.image_fname_close_button = ('icons/cil-power-standby.png')
self.close_button = QPushButton(self)
self.close_button.move(210, 0)
self.close_button.resize(100, 100)
self.close_button.setIcon(
QIcon(QPixmap(self.image_fname_close_button)))
# Animation close_button
self.close_button.installEventFilter(self)
self.timer_close_button = QtCore.QTimer()
self.timer_close_button.timeout.connect(
lambda: self.onRotate('close_button', self.val))
def eventFilter(self, obj, event):
if self.min_button is obj:
if event.type() == QtCore.QEvent.Enter:
self.val = 1
self.timer_min_button.start(60)
elif event.type() == QtCore.QEvent.Leave:
self.val = -1
self.timer_min_button.start(80)
elif self.max_button is obj:
if event.type() == QtCore.QEvent.Enter:
self.val = 1
self.timer_max_button.start(60)
elif event.type() == QtCore.QEvent.Leave:
self.val = -1
self.timer_max_button.start(80)
elif self.close_button is obj:
if event.type() == QtCore.QEvent.Enter:
self.val = 1
self.timer_close_button.start(60)
elif event.type() == QtCore.QEvent.Leave:
self.val = -1
self.timer_close_button.start(80)
return super().eventFilter(obj, event)
def onRotate(self, name_button, val=0):
self.i += val
self.angle += 45 * val
if self.angle <= 90 and self.angle >= -90:
t = QtGui.QTransform().rotate(self.angle)
if name_button == 'min_button':
print('Ветка min_button')
pix = QtGui.QPixmap(self.image_fname_min_button).transformed(t)
image_rotated_min_button = f'{os.path.splitext(self.image_fname_min_button)[0]}_rotated.png'
pix.save(image_rotated_min_button)
self.max_button.setIcon(QtGui.QIcon(image_rotated_min_button))
elif name_button == 'max_button':
print('Ветка max_button')
pix = QtGui.QPixmap(self.image_fname_max_button).transformed(t)
image_rotated_max_button = f'{os.path.splitext(self.image_fname_max_button)[0]}_rotated.png'
pix.save(image_rotated_max_button)
self.max_button.setIcon(QtGui.QIcon(image_rotated_max_button))
elif name_button == 'close_button':
print('Ветка close_button')
pix = QtGui.QPixmap(
self.image_fname_close_button).transformed(t)
image_rotated_close_button = f'{os.path.splitext(self.image_fname_close_button)[0]}_rotated.png'
pix.save(image_rotated_close_button)
self.max_button.setIcon(
QtGui.QIcon(image_rotated_close_button))
else:
self.timer_min_button.stop()
self.timer_max_button.stop()
self.timer_close_button.stop()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Помогите понять что я делаю не так.
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class PushButton(QPushButton):
def __init__(self, img, *args, **kwargs):
super(PushButton, self).__init__(*args, **kwargs)
self.rotation = 0
self.amount_rotation = 0
self.angle = 45
self.pixmap = QPixmap(img)
self._width = self.pixmap.size().width()
self._height = self.pixmap.size().height()
self.pixmap = self.pixmap.scaled(self._width, self._height)
pm = QPixmap(self._width, self._height)
rectF = QRectF(0, 0, self._width, self._height)
painter = QPainter(pm)
painter.drawPixmap(rectF, self.pixmap, rectF)
painter.end()
self.setIcon(QIcon(pm))
self.setIconSize(QSize(50, 50))
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.rotate_item)
def rotate_item(self):
if (self.angle > 0 and self.amount_rotation >= 7) or \
(self.angle < 0 and self.amount_rotation <= 0):
self.timer.stop()
return
self.rotation = (self.rotation + self.angle) % 360
rectF = QRectF(0, 0, self._width, self._height)
pix = QPixmap(self._width, self._height)
painter = QPainter(pix)
painter.translate(rectF.center())
painter.rotate(self.rotation)
painter.translate(-rectF.center())
painter.drawPixmap(0, 0, self.pixmap)
painter.end()
self.setIcon(QIcon(pix))
if self.angle > 0:
self.amount_rotation += 1
else:
self.amount_rotation -= 1
def enterEvent(self, event):
self.angle = 45
self.timer.stop()
self.timer.start(100)
def leaveEvent(self, event):
self.angle = -45
self.timer.stop()
self.timer.start(100)
class Window(QWidget):
def __init__(self):
super().__init__()
self.min_button = PushButton("lena50.png", self)
self.max_button = PushButton("monkey50.png", self)
self.close_button = PushButton("orig50.jpg", self)
layout = QHBoxLayout(self)
layout.addWidget(self.min_button)
layout.addWidget(self.max_button)
layout.addWidget(self.close_button)
if __name__=="__main__":
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
lena50.png
monkey50.png
orig50.jpg



