qtpropertyanimation только изменить масштаб - PullRequest
0 голосов
/ 03 мая 2018

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

Вот класс аниматора

class Animator:
    def __init__(self, animation_config, num_rows, num_cols, background_colour, parent, user_idx = 0, resolution_width = 1920,
                  resolution_height = 1200, log_file_path = "coordinates.txt"):
        with open(log_file_path, "w") as log_file:
            log_file.write("")

        circle = animation_config["circle"]
        self.__cur_circle = None
        self.__cur_colour = None
        self.__animated_colour = QColor(*circle["colour"])
        self.__log_file_path = log_file_path

        # Initialize the circle table

        diamond_square = DiamondSquare()
        self.__user_idx = user_idx % 64
        shift_xn = diamond_square.dx[user_idx]
        shift_yn = diamond_square.dy[user_idx]
        intv_x = (resolution_width - 20) / 10
        intv_y = (resolution_height - 20) / 10
        print(shift_xn,shift_yn)
        self.__circle_table = []
        y = 0
        for i in range (11):
            circles = []
            x = 0
            for j in range (11):
                cir_x = (j * intv_x) + shift_xn
                cir_y = (i * intv_y) + shift_yn
                print(cir_x,cir_y)
                if cir_x <= resolution_width and cir_y <= resolution_height:
                    circles.append(EllipseObject(parent,cir_x,cir_y, x, y, intv_x, intv_y,
                                                 hidden_colour = background_colour,
                                                 display_colour=self.__animated_colour))
                    x += 1
            y += 1

            self.__circle_table.append(circles)

        # Initalize the first animation
        self.__first = QPropertyAnimation()
        self.__first.setPropertyName(b"scale")
        self.__first.setDuration(animation_config["animation_duration"])
        self.__first.setStartValue(2)
        self.__first.setEndValue(1)

и вот мой класс EllipseObject

class EllipseObject(QGraphicsWidget):
    def __init__(
        self,
        parent,
        x = 0,
        y = 0,
        ind_x = 0,
        ind_y = 0,
        intv_x = 0,
        intv_y = 0,
        width = 20,
        height = 20,
        hidden = True,
        hidden_colour = QColor(Qt.white),
        display_colour = QColor(Qt.black)
        ):

        super().__init__(parent)
        self.__x = x
        self.__y = y
        self.__ind_x = ind_x
        self.__ind_y = ind_y
        self.__intv_x = intv_x
        self.__intv_y = intv_y
        self.__height = height
        self.__width = width
        self.hidden = hidden
        self.hidden_colour = hidden_colour
        self.display_colour = display_colour

    def paint(self, painter, option, widget = None):
        colour = QColor(Qt.white) if self.hidden else self.display_colour
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(colour)
        painter.setBrush(QBrush(colour))
        # painter.drawEllipse(self.__x, self.__y, self.__width, self.__height)
        painter.drawEllipse(self.boundingRect())
        # point = self.mapToScene(self.boundingRect().center())
        # print("Draw this ",point.x(), point.y())

    def get_coordinates(self):
        point = self.mapToScene(self.boundingRect().center())
        return (point.x(), point.y())

    def boundingRect(self):
        return QRectF(self.__x,
                      self.__y,
                      self.__height, self.__width)

1 Ответ

0 голосов
/ 03 мая 2018

Что вы, вероятно, наблюдаете, так это то, что он поднимается относительно верхнего левого угла и создаст впечатление, что он движется. QGraphicsItem имеет свойство, называемое transformOriginPoint, относительно которого выполняются преобразования, такие как вращение и масштабирование, и которое находится в точке (0, 0). В вашем случае в вашем коде есть несколько ошибок, вы должны установить позицию с setPos(), а не с boundingRect(), чтобы при масштабировании относительно центра элемента было установлено, что boundingRect() симметричен.

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

class EllipseObject(QGraphicsWidget):
    def __init__(
        self,
        parent=None,
        x = 0,
        y = 0,
        ind_x = 0,
        ind_y = 0,
        intv_x = 0,
        intv_y = 0,
        width = 20,
        height = 20,
        hidden = True,
        hidden_colour = QColor(Qt.white),
        display_colour = QColor(Qt.black)
        ):

        super().__init__(parent)
        self.__x = x
        self.__y = y
        self.__ind_x = ind_x
        self.__ind_y = ind_y
        self.__intv_x = intv_x
        self.__intv_y = intv_y
        self.__height = height
        self.__width = width
        self.hidden = hidden
        self.hidden_colour = hidden_colour
        self.display_colour = display_colour
        self.setPos(self.__x, self.__y)

    def paint(self, painter, option, widget = None):
        colour = QColor(Qt.white) if self.hidden else self.display_colour
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(colour)
        painter.setBrush(QBrush(colour))
        # painter.drawEllipse(self.__x, self.__y, self.__width, self.__height)
        painter.drawEllipse(self.boundingRect())

    def get_coordinates(self):
        return (self.pos().x(), self.pos().y())

    def boundingRect(self):
        return QRectF(-0.5*self.__width,
                      -0.5*self.__height,
                      self.__height, self.__width)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    w = QGraphicsView()
    scene = QGraphicsScene(w)
    w.setScene(scene)
    it = EllipseObject(x=100, y=100, hidden=False)
    scene.addItem(it)

    animation = QPropertyAnimation(it, b"scale")
    animation.setDuration(2000)
    animation.setStartValue(2)
    animation.setEndValue(1)
    animation.start()
    w.show()
    sys.exit(app.exec_())

Примечание:

Вместо использования флага с именем hidden, используйте setVisible(boolean), show() или hide() напрямую. В Qt уже реализовано много методов, колесо не изобретает .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...