qt - создать экземпляр чертежа с помощью QPainter - PullRequest
0 голосов
/ 26 апреля 2020

Итак, я нарисовал круг с помощью QPainter.

Мой вопрос: кому я могу сохранить этот круг в переменной, чтобы я мог с ним работать? Я хочу сделать анимацию с кружком.

QPainter painter(this);
painter.setPen(dottedPen);
painter.drawEllipse(QRect(160,260,80,80));

1 Ответ

0 голосов
/ 26 апреля 2020

Вы можете реализовать свой собственный класс для Ellipse со всем необходимым вам свойством. А затем установите QPropertyAnimation для любой вашей собственности. Вот небольшой пример. Ellipse class (с 4 пользовательскими свойствами):

class Ellipse : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
    Q_PROPERTY(QPoint center READ center WRITE setCenter NOTIFY centerChanged)
    Q_PROPERTY(int radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged)
    Q_PROPERTY(int radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
public:
    explicit Ellipse(QObject *parent = 0);

    void setWidgetToPaint(QWidget* widget);

    void paint();

    void setVisible(const bool visible);
    bool visible() const;

    void setCenter(const QPoint& center);
    const QPoint& center() const;

    void setRadiusX(const int rx);
    int radiusX() const;

    void setRadiusY(const int ry);
    int radiusY() const;

signals:
    void centerChanged();
    void radiusXChanged();
    void radiusYChanged();
    void visibleChanged();

public slots:

private:
    QPointer<QWidget> m_widgetToPaint;
    bool m_isVisible;
    QPoint m_center;
    int m_rx;
    int m_ry;
};

Ellipse::Ellipse(QObject *parent) :
    QObject(parent),
    m_widgetToPaint(nullptr),
    m_isVisible(false),
    m_rx(1),
    m_ry(1)
{
}

void Ellipse::setWidgetToPaint(QWidget *widget)
{
    m_widgetToPaint = widget;
    if (widget)
    {
        connect(this, SIGNAL(visibleChanged()), m_widgetToPaint.data(), SLOT(repaint()));
        connect(this, SIGNAL(centerChanged()), m_widgetToPaint.data(), SLOT(repaint()));
        connect(this, SIGNAL(radiusXChanged()), m_widgetToPaint.data(), SLOT(repaint()));
        connect(this, SIGNAL(radiusYChanged()), m_widgetToPaint.data(), SLOT(repaint()));
    }
}

void Ellipse::paint()
{
    if(!m_widgetToPaint)
    {
        return;
    }

    if (!m_isVisible)
    {
        return;
    }

    QPainter painter(m_widgetToPaint);
    painter.drawEllipse(m_center, m_rx, m_ry);
}

void Ellipse::setCenter(const QPoint &center)
{
    bool needNotify = m_center != center;
    m_center = center;
    if (needNotify)
    {
        emit centerChanged();
    }
}

const QPoint & Ellipse::center() const
{
    return m_center;
}

void Ellipse::setRadiusX(const int rx)
{
    bool needNotify = m_rx != rx;
    m_rx = rx;
    if (needNotify)
    {
        emit radiusXChanged();
    }
}

int Ellipse::radiusX() const
{
    return m_rx;
}

void Ellipse::setRadiusY(const int ry)
{
    bool needNotify = m_ry != ry;
    m_ry = ry;
    if (needNotify)
    {
        emit radiusYChanged();
    }
}

int Ellipse::radiusY() const
{
    return m_ry;
}

void Ellipse::setVisible(const bool visible)
{
    bool needNotify = m_isVisible != visible;
    m_isVisible = visible;
    if (needNotify)
    {
        emit visibleChanged();
    }
}

bool Ellipse::visible() const
{
    return m_isVisible;
}

А теперь создайте экземпляр эллипса внутри вашего виджета. И переопределить paintEvent ваш виджет

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void paintEvent(QPaintEvent *event);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MainWindow *ui;
    Ellipse m_ellipse;
};

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_ellipse.setWidgetToPaint(this);
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QMainWindow::paintEvent(event);
    m_ellipse.paint();
}

Чтобы сделать эллипс видимым, просто установите visible=true

void MainWindow::on_pushButton_clicked()
{
    m_ellipse.setVisible(true);
    m_ellipse.setCenter(QPoint(30, 30));
    m_ellipse.setRadiusX(25);
    m_ellipse.setRadiusY(15);
}

Также теперь вы можете установить любую анимацию для пользовательских свойств. Вот пример для center property

void MainWindow::on_pushButton_2_clicked()
{
    QPropertyAnimation *animationCenter = new QPropertyAnimation(&m_ellipse, "center", this);
    animationCenter->setStartValue(QPoint(30, 30));
    animationCenter->setEndValue(QPoint(100, 100));
    animationCenter->setDuration(3000);
    animationCenter->start(QAbstractAnimation::DeleteWhenStopped);
}
...