#c #qt
Вопрос:
Я хочу загрузить изображение в Qt и переместить его вдоль оси x в анимации.
Вот и все. Я искал, но большинство примеров намного сложнее или используют геометрические фигуры, использующие функции рисования Qt.
У кого-нибудь здесь есть ссылка на образец, который просто описывает мой простой вариант использования?
Комментарии:
1. Проверьте doc.qt.io/qt-5/qpropertyanimation.html , это дает простой пример. В вашем случае вы хотите анимировать
x
свойство, а неgeometry
. doc.qt.io/qt-5/qwidget.html#properties2. Спасибо, похоже, вы в правильном направлении. В примере используется «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. Да, не беспокойтесь, я понимаю ваши намерения! В качестве дополнения я просто хотел указать на потенциальные утечки памяти, которые можно было бы вызвать, не тщательно скопировав этот класс в свою программу. Чтобы сделать сообщение более кратким!!!