旋转的沙漏
目录
- 参考
- spin.cpp
- main.cpp
- spin.h
- spin.cpp
- 效果
参考
解决:[QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1] 需要在哪个控件上绘制,就要在哪个控件类中重写 paintEvent() ,所以本项目 需要使用自定义的MyQLabel继承QLabel
正点原子案例
最近毕业设计需要用到旋转的沙漏,记忆中好像在正点原子学过
spin.cpp
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \\main.cpp \\spin.cppHEADERS += \\spin.hFORMS +=# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \\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();
}
效果