Простой пример перемещения изображения (в виде анимации) в Qt?

#c #qt

Вопрос:

Я хочу загрузить изображение в Qt и переместить его вдоль оси x в анимации.

Вот и все. Я искал, но большинство примеров намного сложнее или используют геометрические фигуры, использующие функции рисования Qt.

У кого-нибудь здесь есть ссылка на образец, который просто описывает мой простой вариант использования?

Комментарии:

1. Проверьте doc.qt.io/qt-5/qpropertyanimation.html , это дает простой пример. В вашем случае вы хотите анимировать x свойство, а не geometry . doc.qt.io/qt-5/qwidget.html#properties

2. Спасибо, похоже, вы в правильном направлении. В примере используется «mywidget». В случае изображения, какой тип я бы использовал для этого виджета? QImage? Я абсолютный новичок в Qt.

3. Ответ зависит от того, как вы используете изображение. Например, если изображение является просто частью перехода пользовательского интерфейса, может иметь смысл загрузить его в QPixmap, затем установить его на QLabel и анимировать метку. Если вы предполагаете более сложную сцену с несколькими движущимися изображениями, вы можете посмотреть на QGraphicsScene . Не могли бы вы уточнить контекст?

4. Сначала я протестирую его на одном изображении. Думаю, подойдет QLabel. Спасибо.

Ответ №1:

Очень простая реализация с QTimer помощью .

Результат:

введите описание изображения здесь

Итак, мой код:

 #ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QTimer>
#include <QImage>
#include <QGraphicsEllipseItem>
#include <QVBoxLayout>
#include <QLabel>

class SimpleAnimation : public QWidget
{
    Q_OBJECT

public:
    SimpleAnimation(QWidget *parent = nullptr)
        : QWidget(parent)
    {
        QPixmap image(":/0_0.png");
        m_label = new QLabel(this);
        m_label->setPixmap(image);

        QVBoxLayout* mainLayout = new QVBoxLayout;
        mainLayout->addWidget(m_label);

        setLayout(mainLayout);
        m_timer = new QTimer(this);
        connect(m_timer, amp;QTimer::timeout, this, amp;SimpleAnimation::onTimeout);
        m_timer->start(100);

    }
    ~SimpleAnimation()
    {
    }

protected slots:
    void onTimeout()
    {
        QPoint oldPosition = m_label->pos();
        QPoint newPosition = QPoint(oldPosition.x()   10, oldPosition.y());

        m_label->move(newPosition);
    }

private:
    QLabel* m_label;
    QTimer* m_timer;

};
#endif // MAINWINDOW_H
 

Когда выдается сигнал тайм-аута, мы получаем QLabel позицию, добавляем 10 к x и перемещаем нашу QLabel позицию на новую.

Конечно, вы можете использовать QGraphicsScene для изображений. Лучше подходит для управления большим количеством 2D-объектов. QGraphicsScene имеет значение QGraphicsView , но для одного изображения в этом нет необходимости.

Комментарии:

1. Будьте осторожны, ваш класс SimpleAnimation небезопасен для памяти!

2. Я добавляю эти соединения: connect(m_timer, amp;QObject::destroyed, this, amp;SimpleAnimation::timerDelete);connect(m_label, amp;QObject::destroyed, this, amp;SimpleAnimation::timerDelete); connect(mainLayout, amp;QObject::destroyed, this, amp;SimpleAnimation::timerDelete); в мой конструктор и void timerDelete() { qDebug()<< "timerDelete"; } слот, чтобы проверить, удаляет ли он или нет. Он возвращает меня timerDelete три раза. Итак, весь мой объект уничтожен, и у него нет утечки памяти

3. Я не знаю, что connect это значит, но если вы справитесь с этим, тогда О’кей! Хотя, я думаю, что способ, которым вы реализовали класс, сложен, и, вероятно, его будет трудно повторно использовать в будущем кому-то другому или даже вам самим!

4. @АндреасХаджигеоргиу спасибо за совет, вы правы, но я делаю простой пример, который новичок может скопировать в IDE и увидеть результат. Естественно, что в производственных проектах программисты создают лучшие проекты

5. Да, не беспокойтесь, я понимаю ваши намерения! В качестве дополнения я просто хотел указать на потенциальные утечки памяти, которые можно было бы вызвать, не тщательно скопировав этот класс в свою программу. Чтобы сделать сообщение более кратким!!!