Qt:玩转QPainter后转之太极图(步骤详细、包含源码)

news2024/9/25 11:11:40

前言

简单了解了QPainter之后还是要做两个小例子练一练,不实际去做,只看看函数是没啥太大提升的,这里就简单画一个太极图。

正文

在这里插入图片描述

我们都知道太极分为阴阳鱼两部分,阴鱼(黑色)有个白色鱼眼,阳鱼(白色)有个黑色鱼眼;所以我们在画图的时候也可以分成阴阳两部分来画
单看阳鱼
在这里插入图片描述
不算鱼眼的话可以分成三部分,我们可以先画一个大半圆,用大半圆减去上面一个小半圆,再加上下面一个小半圆即可
阴鱼正好相反先画一个大半圆,用大半圆减去下面一个小半圆,再加上上面一个小半圆即可
关键代码

void BGPainter::drawTaiJi(QPainter& painter)
{
    // 先保存绘图设置
    painter.save();
    // 通过旋转坐标系统实现太极图的旋转
    painter.rotate(m_angle);

    // 白鱼
    QPainterPath circle, temp;
    // <<左移乘2
    circle.arcTo(-m_radius, -m_radius, m_radius << 1, m_radius << 1, 270, 180);
    // >>右移除2
    temp.addEllipse(QPointF(0, -m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 上面减一个小半圆
    circle -= temp;
    temp.clear();
    temp.addEllipse(QPointF(0, m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 下面加上一个小半圆
    circle += temp;
    painter.fillPath(circle, Qt::white);
    
    // 黑鱼
    circle.clear();
    circle.arcTo(-m_radius, -m_radius, m_radius << 1, m_radius << 1, 90, 180);
    temp.clear();
    temp.addEllipse(QPointF(0, m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 下面减一个小半圆
    circle -= temp;
    temp.clear();
    temp.addEllipse(QPointF(0, -m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 上面加上一个小半圆
    circle += temp;
    painter.fillPath(circle, Qt::black);

    painter.restore();
}

效果如下
在这里插入图片描述
现在再把鱼眼添加上,再加一个定时器来实现旋转即可
完整代码

#ifndef BGPAINTER_H
#define BGPAINTER_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class BGPainter; }
QT_END_NAMESPACE
enum Speed {
    VERYFAST = 5,
    FAST = 10,
    MEDIUM = 50,
    LOW = 100,
    LOWLOW = 200
};


class BGPainter : public QWidget
{
    Q_OBJECT

public:
 
    BGPainter(QWidget *parent = nullptr);
    void updateInterval(int speed);
    void initcboSpeed();
    ~BGPainter();
protected:
    void paintEvent(QPaintEvent* event) override;
    void drawTaiJi(QPainter& painter);

private slots:
    void on_btnBeignRotate_clicked();
    void on_btnEndRotate_clicked();

private:
    Ui::BGPainter *ui;
    // 太极图半径
    int m_radius;
    // 设置个定时器使得太极图旋转
    QTimer* m_timer;
    // 定时器的时间间隔
    int m_interval;
    // 旋转的角度
    int m_angle;
};
#endif // BGPAINTER_H

//cpp文件
#include "bgpainter.h"
#include <QPointF>
#include "qpainter.h"
#include "qpainterpath.h"
#include "qtimer.h"
#include "qpen.h"
#include "qbrush.h"
#include "ui_bgpainter.h"

BGPainter::BGPainter(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::BGPainter)
    , m_radius(100)
    , m_angle(0)
    , m_interval(200)
{
    ui->setupUi(this);
    m_timer = new QTimer(0);
    // 默认时间间隔为2ms
    m_timer->setInterval(m_interval);
    connect(m_timer, &QTimer::timeout, [=](){
        // 触发72次定时器才算完整一圈
        m_angle += 5;
        m_angle %= 360;
        update(); });
    initcboSpeed();
}

void BGPainter::updateInterval(int speed)
{
    m_interval = speed;
    m_timer->setInterval(m_interval);
}

void BGPainter::initcboSpeed()
{
    ui->cboSpeed->addItem("LOWLOW",static_cast<int>(Speed::LOWLOW));
    ui->cboSpeed->addItem("LOW",static_cast<int>(Speed::LOW));
    ui->cboSpeed->addItem("MEDIUM",static_cast<int>(Speed::MEDIUM));
    ui->cboSpeed->addItem("FAST",static_cast<int>(Speed::FAST));
    ui->cboSpeed->addItem("VERYFAST",static_cast<int>(Speed::VERYFAST));
    connect(ui->cboSpeed,QOverload<int>::of(&QComboBox::currentIndexChanged),this,[=](){
        int index = ui->cboSpeed->currentIndex();
        Speed speed = (Speed)ui->cboSpeed->itemData(index).toInt();
        updateInterval(speed);
    });
}

BGPainter::~BGPainter()
{
    delete ui;
    if (m_timer)
    {
        if (m_timer->isActive())
            m_timer->stop();

        delete m_timer;
        m_timer = nullptr;
    };
}

void BGPainter::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    // 图形和文本抗锯齿
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    // 将绘图起点移动到窗口中心
    painter.translate(width() / 2, height() / 2);
    // 画太极
    drawTaiJi(painter);

}

void BGPainter::drawTaiJi(QPainter& painter)
{
    // 先保存绘图设置
    painter.save();
    // 通过旋转坐标系统实现太极图的旋转
    painter.rotate(m_angle);

    // 白鱼
    QPainterPath circle, temp;
    // <<左移乘2
    circle.arcTo(-m_radius, -m_radius, m_radius << 1, m_radius << 1, 270, 180);
    // >>右移除2
    temp.addEllipse(QPointF(0, -m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 上面减一个小半圆
    circle -= temp;
    temp.clear();
    temp.addEllipse(QPointF(0, m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 下面加上一个小半圆
    circle += temp;
    painter.fillPath(circle, Qt::white);
    // 黑鱼眼
    temp.clear();
    temp.addEllipse(QPointF(0, m_radius >> 1), m_radius >> 3, m_radius >> 3);
    painter.fillPath(temp, Qt::black);
    // 黑鱼
    circle.clear();
    circle.arcTo(-m_radius, -m_radius, m_radius << 1, m_radius << 1, 90, 180);
    temp.clear();
    temp.addEllipse(QPointF(0, m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 下面减一个小半圆
    circle -= temp;
    temp.clear();
    temp.addEllipse(QPointF(0, -m_radius >> 1), m_radius >> 1, m_radius >> 1);
    // 上面加上一个小半圆
    circle += temp;
    painter.fillPath(circle, Qt::black);
    // 白鱼眼
    temp.clear();
    temp.addEllipse(QPointF(0, -m_radius >> 1), m_radius >> 3, m_radius >> 3);
    painter.fillPath(temp, Qt::white);

    painter.restore();
}

void BGPainter::on_btnBeignRotate_clicked()
{
    m_timer->start();
}

void BGPainter::on_btnEndRotate_clicked()
{
    if (m_timer->isActive()) {
        m_timer->stop();
    }
}

最后效果

taijiYanshi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2110200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Notes,无代码应用开发王者归来!

大家好&#xff0c;才是真的好。 连续一个星期都在讲HCL Notes Domino 14.5 EAP1&#xff0c;大家是不是已经感到疲惫了&#xff1f;和大家一样&#xff0c;我并没有。 因此&#xff0c;看了一下9月4号晚上的HCL Notes Domino 14.5 EAP1在线广播回顾&#xff0c;发现了几个大…

模拟RabbitMQ实现消息队列【项目】

文章目录 1. 项目介绍什么是RabbitMQ&#xff1f; 2. 开发环境3. 技术选型3.1ProtoBuf使用介绍&#xff1a;3.2 Muduo库3.3 SQLite3什么是SQLIte&#xff1f;为什么要用SQLite&#xff1f; 3.4 Gtest什么是Gtest 4. 需求分析4.1 核心概念4.2 核心API4.3 交换机类型4.4 持久化4.…

UVa1389/LA3709 Hard Life

UVa1389/LA3709 Hard Life 题目链接题意输入格式输出格式 分析AC 代码 题目链接 本题是2006年icpc欧洲区域赛东北欧赛区的H题 题意 约翰是一家公司的CEO。公司的股东决定让他的儿子斯科特成为公司的经理。约翰十分担心&#xff0c;儿子会因为在经理岗位上表现优异而威胁到他CE…

IPv4地址学习

今天学习了IPv4&#xff0c;做下学习笔记&#xff1a; 什么是IPv4&#xff1f; IPv4地址是网络层地址&#xff0c;用于标识网络中的每个节点。 什么是子网&#xff1f;什么是主类子网划分&#xff1f; 我们将IP地址划分为网络位和主机位 一个地址为192.168.1.2/24&#xff…

【HTML】置换元素(替换元素)

● 它的内容不是由元素的标签内的内容决定的,而是由元素的属性决定的 ● 可以通过CSS设置宽度和高度。 常见的置换元素主要包括以下几种: <img> 元素:用于嵌入图像,通过 src 属性指定图像的路径。例如:<img src="example.jpg" alt="示例图片&quo…

场景感知技术带您重塑未来生活的新篇章

在科技日新月异的今天&#xff0c;场景感知技术正以前所未有的速度渗透到我们生活的方方面面&#xff0c;成为连接物理世界与数字世界的桥梁&#xff0c;重塑着人类的认知方式与生活体验。这项技术通过综合运用传感器、大数据分析、人工智能等前沿科技&#xff0c;实现对周围环…

C++多态 学习笔记(上)

本文涉及的指针都是 4bytes 。 如果要其他平台下&#xff0c;部分代码需要改动。比如&#xff1a;如果是 x64 程序&#xff0c;则需要考虑指针是 8bytes 问题 等等。 什么是多态&#xff1f; 举个例子&#xff1a;比如 买票这个行为 &#xff0c;当 普通人 买票时&#xff0c;…

短剧APP系统搭建,短剧市场的发展机遇

短剧作为近几年内发展快速的行业&#xff0c;一直深受大众的欢迎&#xff0c;各种让观众上头的短剧层出不穷&#xff0c;深深吸引着大众。短剧的巨大发展前景也吸引了大量资本涌入市场&#xff0c;目前&#xff0c;短剧入局者也都获得了不菲的经济收益&#xff01; 随着短剧行…

C++下标+【】、迭代器、范围for、迭代器对于其他容器都是通用的、迭代器可以更好的跟算法配合、rbegin和rend函数、const修饰的迭代器等的介绍

文章目录 前言一、 下标 【】二、 迭代器1.begin2. end3. 使用迭代器遍历string类对象 三、范围for(语法糖)五、迭代器对于其他容器都是通用的六、迭代器可以更好地跟算法配合七、 rbegin 和 rend函数八、 const 修饰的迭代器总结 前言 C下标【】、迭代器、范围for、迭代器对…

JavaEE---Spring MVC(5)

MVC学习小案例3 留言板案例 后端代码 测试 点击刷新的时候页面的这些记录仍在 一个小tips 我们在日常中写的时候会经常写到get和set方法,这会使整个代码看起来非常多不好看,这里我们引入一个新的依赖解决这个问题 引入LomBok依赖 那要是个别情况下我们不想获取他的ge…

高集成度双通道差分式电容型传感芯片-MC11

工采电子代理的MC11S、MC11T是一款高集成度双通道电容型传感芯片&#xff0c;芯片直接与被测物附近的差分电容极板相连&#xff0c;通过谐振激励并解算测量微小电容的变化。激励频率在0.1~20MHz范围内可配置&#xff0c;其频率测量输出为16bit数字信号&#xff0c;对应的电容感…

Ventoy启动盘制作

然后直接将系统的ISO镜像直接拷贝进去&#xff0c;就能直接使用

69页PPT全面预算管理体系的框架与落地

一、明确企业战略目标企业战略目标是预算指标体系确立的根本出发点。它为预算指标的设定提供了方向和指导。 深入分析企业长期发展规划 企业需要对自身的长期发展规划进行全面、深入的分析。这包括对市场趋势、行业竞争态势、技术发展方向等外部环境因素的研究&#xff0c;以…

AI技术颠覆游戏开发:谷歌DeepMind GameNGen实时生成《DOOM》探秘

引言 近年来&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;在图像和视频生成领域取得了巨大突破。然而&#xff0c;谁能想到&#xff0c;这项技术正逐渐渗透进游戏开发领域&#xff0c;且潜力巨大。2023年8月29日&#xff0c;谷歌DeepMind发布了名为《扩散模型是实时…

【舍入,取整,取小数,取余数丨Excel 函数】

数学函数 1、Round函数 Roundup函数 Rounddown函数 取整&#xff1a;(Int /Trunc)其他舍入函数&#xff1a; 2、Mod函数用Mod函数提取小数用Mod函数 分奇偶通过身份证号码判断性别 1、Round函数 Roundup函数 Rounddown函数 Round(数字&#xff0c;保留几位小数)&#xff08;四…

解除网站禁用右键 解除禁用选择方法 并允许复制

限制我复制&#xff0c;太恶心了&#xff0c;别用技术作恶&#xff01;&#xff01;&#xff01; 一般HTML网站禁止右键选择的方法 <body ondragstart"return false" oncontextmenu"return false" onselectstart"return false">解除网站…

遇到“msvcp120.dll丢失”的错误提示?来看看msvcp120.dll丢失的解决方法都有哪些?

遇到“msvcp120.dll丢失”的错误提示可能会让人感到焦虑&#xff0c;尤其是当你尝试运行某个应用程序或游戏时突然接收到这样的消息。​msvcp120.dll​是Microsoft Visual C 2013 Redistributable Package 中的一个文件&#xff0c;主要负责C标准库中的功能&#xff0c;比如输入…

C++第四十六弹---解锁多线程编程的奥秘:<thread>库深入探索

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1 线程库 1.1 thread类的简单介绍 1.2 线程函数参数 1.3 原子性操作库(atomic) 1.4 lock_guard与unique_lock 1.4.1 mutex的种类 1.4.2 loc…

python-小理的三角形

题目描述 小理有一个数组长度大小为 n &#xff0c;数组中有 n 个正整数。 现在小理请你从其中选出三个元素&#xff08;注意选择元素的下标不能相同&#xff0c;但是其值可以相同&#xff09;组成一个三角形。 无法做到&#xff0c;请输出一行一个字符串"No solution&quo…

SQL进阶技巧:每年在校人数统计 | 区间重叠问题

目录 0 问题分析 1 数据准备 2 问题分析 3 小结 区间重叠问题 0 问题分析 有一个录取学生人数表 in_school_stu&#xff0c;记录的是每年录取学生的人数及录取学生的学制&#xff0c;计算每年在校学生人数。 1 数据准备 create table in_school_stu as ( select stack(5,…