旋转的沙漏

参考

解决:[QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1] 需要在哪个控件上绘制,就要在哪个控件类中重写 paintEvent() ,所以本项目 需要使用自定义的MyQLabel继承QLabel

正点原子案例

最近毕业设计需要用到旋转的沙漏,记忆中好像在正点原子学过

spin.cpp

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    spin.cpp

HEADERS += \
    spin.h

FORMS +=

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    res.qrc

main.cpp

#include "spin.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SPIN w;
    w.show();
    return a.exec();
}

spin.h

#ifndef SPIN_H
#define SPIN_H

#include <QWidget>
#include <QTimer>
#include <QPainter>

class SPIN : public QWidget
{
    Q_OBJECT
public:
    explicit SPIN(QWidget *parent = nullptr);


protected:
    void paintEvent(QPaintEvent *); /* 重写父类下的 paintEvent方法*/

private:
    /* 定时器,用于定时更新界面 */
    QTimer *timer;
    /* 角度 */
    int angle;
private slots:
    void timerTimeOut();
};

#endif // SPIN_H

spin.cpp

#include "spin.h"

SPIN::SPIN(QWidget *parent)
    : QWidget{parent}
{
    /* 设置主窗口位置及颜色 */
    this->setGeometry(0, 0, 1024, 600);
    setPalette(QPalette(Qt::gray));
    setAutoFillBackground(true);

    /* 定时器实例化 */
    timer = new QTimer(this);

    /* 默认角度为 0 */
    angle = 0;

    /* 定时 100ms */
    timer->start(100);

    /* 信号槽连接 */
    connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
}

/* 重写父类下的 paintEvent方法*/
void SPIN::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e)

    /* 指定父对象,this 指本窗口 */
    QPainter painter(this);

    /* 设置抗锯齿,流畅转换 */
    painter.setRenderHints(QPainter::Antialiasing
                           | QPainter::SmoothPixmapTransform);
    /* 计算旋转角度 */
    if (angle++ == 360)
        angle = 0;

    /* QPixmap 类型对象 */
    QPixmap image;

    /* 加载 */
    image.load(":/spin.webp");
    image=image.scaled(image.size() / 2); // 缩放为原大小的一半

    /* QRectF 即,继承 QRect(Qt 的矩形类),F 代表精确到浮点类型 */
    QRectF rect((this->width() - image.width()) / 2-200,
                (this->height() - image.height()) / 2,
                image.width(),
                image.height());

    /* 默认参考点为左上角原点(0,0),因为旋转需要以图形的中心为参考点,
         * 我们使用 translate 把参考点设置为 CD 图形的中心点坐标 */
    painter.translate(0 + rect.x() + rect.width() / 2,
                      0 + rect.y() + rect.height() / 2);

    /* 旋转角度 */
    painter.rotate(angle);

    /* 现在参考点为 CD 图形的中心,我们需要把它设置回原点的位置,
          * 所以需要减去上面加上的数 */
    painter.translate(0 - (rect.x() + rect.width() / 2),
                      0 - (rect.y() + rect.height() / 2));

    /* 画图,QPainter 提供了许多 drawX 的方法 */
    painter.drawImage(rect, image.toImage(), image.rect());

    /* 再画一个矩形 */
    painter.drawRect(rect.toRect());

    {
        /* 指定父对象,this 指本窗口 */
        QPainter painter2(this);

        /* 设置抗锯齿,流畅转换 */
        painter2.setRenderHints(QPainter::Antialiasing
                               | QPainter::SmoothPixmapTransform);
        /* 计算旋转角度 */
        if (angle++ == 360)
            angle = 0;

        /* QPixmap 类型对象 */
        QPixmap image2;

        /* 加载 */
        image2.load(":/sandClock.webp");
        image2=image2.scaled(image2.size() / 2); // 缩放为原大小的一半

        /* QRectF 即,继承 QRect(Qt 的矩形类),F 代表精确到浮点类型 */
        QRectF rect2((this->width() - image2.width()) / 2+300,
                    (this->height() - image2.height()) / 2,
                    image2.width(),
                    image2.height());

        /* 默认参考点为左上角原点(0,0),因为旋转需要以图形的中心为参考点,
             * 我们使用 translate 把参考点设置为 图形的中心点坐标 */
        painter2.translate(0 + rect2.x() + rect2.width() / 2,
                          0 + rect2.y() + rect2.height() / 2);

        /* 旋转角度 */
        painter2.rotate(-angle);

        /* 现在参考点为 CD 图形的中心,我们需要把它设置回原点的位置,
              * 所以需要减去上面加上的数 */
        painter2.translate(0 - (rect2.x() + rect2.width() / 2),
                          0 - (rect2.y() + rect2.height() / 2));

        /* 画图,QPainter 提供了许多 drawX 的方法 */
        painter2.drawImage(rect2, image2.toImage(), image2.rect());

        /* 再画一个矩形 */
        painter2.drawRect(rect2.toRect());
    }



}

void SPIN::timerTimeOut()
{
    /* 需要更新界面,不设置不更新 */
    this->update();
}

效果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值