【问题标题】:Pyside6 Animated Rectangle troublePyside6 动画矩形麻烦
【发布时间】:2021-06-29 05:57:07
【问题描述】:

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

这是我的课

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()

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

【问题讨论】:

    标签: python pyside pyside6


    【解决方案1】:

    一种可能的解决方案是创建一个处理不透明度的 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()
    

    【讨论】:

    • 嗨!我还有一个问题)为什么我在 Qlabel 上看到这个 Board-rectangle 如果我使用这个 QLabel 从 QFrame 的 init 创建它,并且看不到我是否尝试在函数中动态创建 Board 实例而不是QFrame 的 init。因此,只需将 Board 实例的创建从 init 剪切/粘贴到函数就会破坏一切/它怎么会发生?
    • @ВладиславСтадник SO规则: 1) cmets仅用于讨论帖子的问题,改进等,不用于其他问题。 2)如果您有问题,请创建一个新帖子。我们是一个高质量的问答网站,所以帖子(和 cmets)必须准确,我们不是咨询服务、辅导等。我们只解决 OP 在他的帖子中提出的问题。请阅读How to Ask 并查看tour
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 2014-02-03
    • 1970-01-01
    相关资源
    最近更新 更多