参考
[解决:[QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1] 需要在哪个控件上绘制,就要在哪个控件类中重写 paintEvent() ,所以本项目 需要使用自定义的MyQLabel继承QLabel]( https://blog.csdn.net/qq_47355554/article/details/129235300)正点原子案例
最近毕业设计需要用到旋转的沙漏,记忆中好像在正点原子学过
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();
}