0

我正在尝试制作褪色的环形矩形区域。我使用了这里的基本代码 刚刚决定扩展它。它只是闪烁的矩形,但我需要平滑的淡入和淡出效果。所以我决定制作一种方法来计算新的不透明度百分比并将其设置为画家。但它不能循环工作。

这是我现在的课

class HighlightRect(QFrame):
board_width = 400  # width of frame
board_height = 400  #height of frame

def __init__(self, parent, x, y, width=50, height=50, blink_speed=1000):
    super().__init__(parent)
    self.blink_speed = blink_speed
    self.opacity_timer = self.blink_speed
    self.board_height = self.parent().height()
    self.board_width = self.parent().width()
    self.square_height = height
    self.square_width = width
    self.highlight_x = x
    self.highlight_y = y


    #self.setFocusPolicy(QtCore.Qt.StrongFocus)
    self.timer_draw = QtCore.QTimer(self)
    self.timer_draw.timeout.connect(self.draw)
    self.timer_draw.start(self.blink_speed)

    self.color = QtCore.Qt.red
    self.is_draw = False
    self.x_apple = 0
    self.y_apple = 0
    self.draw()

def blink(self, painter):
    self.color = QtCore.Qt.red
    while self.opacity_timer >= 0:
        self.opacity_timer -= 1 / 10  # просто подбор
        percents = round(int(self.opacity_timer / self.blink_speed * 100)/100, 1)
        print(percents)
        painter.setOpacity(percents)



def paintEvent(self, event):
    painter = QtGui.QPainter(self)

    print ("Paint Event?")
    if self.is_draw == True:
        print ("Draw")
        #self.color = QtCore.Qt.red
        self.blink_thread = threading.Thread(name='background', target=lambda: self.blink(painter))
        self.blink_thread.start()
    else:

        self.opacity_timer = self.blink_speed
        print ("Do not draw")
        self.color = QtCore.Qt.transparent
        threading.SystemExit = SystemExit
    painter.setPen(self.color)
    painter.drawRect(self.rect)

def draw(self):
    self.is_draw = not self.is_draw
    self.rect = QRect(self.highlight_x, self.highlight_y, self.square_width, self.square_height)
    self.update()

在闪烁函数内部改变不透明度,但在 while 循环外部也可以,但它是静态的。没有变化。在循环中改变不透明度是行不通的。怎么了?也许这里的某个地方是另一种更正确的方式来获得我想要的东西?

4

1 回答 1

2

一种可能的解决方案是创建一个处理不透明度的 QProperty,然后使用 QPropertyAnimation 使更改平滑。

import random
import sys

from PySide6.QtCore import Property, Signal, QPropertyAnimation, QRect, Qt
from PySide6.QtGui import QPainter
from PySide6.QtWidgets import QFrame, QApplication


class Board(QFrame):
    rect_opacity_changed = Signal(name="rectOpacityChanged")

    def __init__(self, parent=None):
        super(Board, self).__init__(parent)

        self._rect_opacity = 1.0
        self._rect = QRect(0, 0, 50, 50)

        self._opacity_animation = QPropertyAnimation(
            targetObject=self, propertyName=b"rect_opacity", duration=3000
        )
        for p, v in ((0.0, 0.0), (0.3, 1.0), (0.7, 1.0), (1.0, 0.0)):
            self._opacity_animation.setKeyValueAt(p, v)

        self._opacity_animation.finished.connect(self.change)

        self.change()

    @Property(float, notify=rect_opacity_changed)
    def rect_opacity(self):
        return self._rect_opacity

    @rect_opacity.setter
    def rect_opacity(self, opacity):
        self._rect_opacity = opacity
        self.rect_opacity_changed.emit()
        self.update()

    def change(self):
        x = random.randint(0, self.width() - self._rect.width())
        y = random.randint(0, self.height() - self._rect.height())
        self._rect.moveTo(x, y)
        self._opacity_animation.start()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setOpacity(self.rect_opacity)
        painter.setPen(Qt.red)
        painter.drawRect(self._rect)


def main():

    app = QApplication([])
    board = Board()
    board.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
于 2021-06-28T21:57:07.077 回答