Qt:玩转QPainter后转之太极图

news2024/9/20 16:56:29

前言

简单了解了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/2092028.html

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

相关文章

2024最详细Maven配置教程

1、Maven 1.1、Maven简介 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性&…

EmbeddedGUI简介

简介 文档地址&#xff1a;欢迎来到EmbeddedGUI的文档 本项目主要面对RAM资源有限&#xff08;<8KB&#xff09;&#xff0c;ROM资源有限&#xff08;<64KB&#xff0c;主要看所需字体和贴图资源&#xff09;&#xff0c;CPU资源还充裕&#xff08;<100MHz&#xff…

PDF Guru Anki - 支持 PDF 处理和 Anki 制卡的多功能工具箱

DF Guru Anki&#xff0c;这是一款能够大幅提升学习和办公效率的工具。 不仅能够帮助我们快速处理 PDF 文件&#xff0c;还能够高效管理各种学习资料&#xff0c;轻松制作 Anki 卡片。 PDF Guru Anki 支持 PDF 合并、拆分、旋转、加密等基本操作&#xff0c;还能够处理水印、书…

企业资产管理是什么?如何做好?权威指南

企业资产管理&#xff08;Enterprise Asset Management, 简称EAM&#xff09;已成为企业提升运营效率、降低维护成本、增强市场竞争力的重要手段。 本文将从企业资产管理的定义、重要性、实施方法及优化策略等方面&#xff0c;提供一份权威的指南&#xff0c;帮助企业更好地理解…

视频结构化从入门到精通——行为分析类应用

行为分析类应用 1. 认识行为分析 监控/判断视频画面中目标的运动过程、携带属性等。从数据中自动识别、跟踪和理解人类或物体行为。 1. 车的行为分析应用 车辆行为分析主要用于监控和管理车辆的动态行为&#xff0c;广泛应用于智能交通、城市管理和安全监控。关键应用包括&…

信息安全--(四)网络安全体系与安全模型(二)

其他安全模型 ■纵深防御模型&#xff1a;①安全保护②安全监测③实时响应④恢复 ■分层防护模型&#xff1a;参考OSI模型&#xff0c;对保护对象进行层次化保护。 ■等级保护模型&#xff1a;将信息系统划分成不同安全保护等级&#xff0c;采取相 应的保护措施。 ■网络生…

使用numpy快速实现统计分析的常用代码实现

文末赠免费精品编程资料~~ NumPy 是 Python 编程语言中用于数值计算的核心库之一&#xff0c;在统计分析方面&#xff0c;它也提供了各种各样的函数来实现统计分析。 NumPy统计分析功能概览 基本统计量&#xff1a;计算平均值、中位数、众数、标准差、方差等。 排序和搜索&a…

8款对比分析:哪款协同办公软件最适合您的团队?

文章介绍了以下几个工具&#xff1a;1. Worktile&#xff1b;2. PingCode&#xff1b;3. 钉钉&#xff1b;4. 有道云协作&#xff1b;5. 云之家&#xff1b;6. 飞书&#xff1b;7. 语雀&#xff1b;8. Airtable。 在当今快节奏的工作环境中&#xff0c;找到一款能够无缝同步文件…

全网最全软件测试面试题(含答案解析+文档)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计&#xff0c;到…

SPI通信(一)

1 硬件多&#xff0c;导致资源浪费&#xff08;速度快&#xff09; 1 就是分别用于发送和接收的两条线路 MOSI和MISO 2 全双工&#xff1a;MOSI(主机发送&#xff0c;从机接收) MISO(从机发送&#xff0c;主机接收) 3 支持总线挂载多设备&#xff08;一主多从&#xff09; …

初试构建工具Webpack

文章目录 一、Webpack概述二、安装Webpack三、Webpack打包实战1、创建index.js2、创建index.html3、运行webpack4、浏览index.html5、添加第二个脚本&#xff08;1&#xff09;创建index2.js&#xff08;2&#xff09;修改index.js&#xff08;3&#xff09;重新运行 webpack&a…

乱弹篇(44)涨洪水了

今&#xff08;2024年8月31日&#xff09;晨&#xff0c;笔者一如既往地骑上小型电三轮车&#xff0c;去到了寄居养老已逾六年的崇州市街子古镇味江河边遛弯健身。放眼远眺&#xff0c;啊&#xff01;涨洪水了。 照片&#xff1a;笔者手机自拍 看那刚刚修建好的&#xff0c;沿…

【C++】1326. 需要安排几位师傅加工零件

问题&#xff1a;1326. 需要安排几位师傅加工零件 类型&#xff1a;贪心 题目描述&#xff1a; 某工厂有 n 个零件加工的师傅&#xff0c;每位师傅每天能够加工出不同数量的零件。 现有 m 个零件要求一天加工完&#xff0c;请问该工厂最少需要派几个师傅来完成这次零件加工任…

兴业证券基于Apache DolphinScheduler的应用实践

文 / 兴业证券股份有限公司 刘洋 石良生 柳君 李致琪 本文来源于网络&#xff0c;如有侵权&#xff0c;请联系删除 任务调度平台&#xff0c;扮演着自动执行预设任务的重要角色&#xff0c;是业务开展过程中不可或缺的一环。随着业务规模的不断扩展&#xff0c;兴业证券每日…

物联网之硬件元器件基础知识介绍、集成电路、电阻器、电容器、电感器、二极管、三极管、晶体管、连接器、传感器、开关、电源

MENU 前言电子元件采购网址三极管持续更新中 前言 序言 硬件元器件是电子设备和系统的基本构成部分&#xff0c;它们在电子产品的设计、制造和功能实现中起着至关重要的作用。 电阻器(Resistor) 功能&#xff1a;电阻器用于限制电流流过电路的流动&#xff0c;并分配电压。它们…

【复旦微FM33 MCU 外设开发指南】外设篇3——SPI

前言 本系列基于复旦微FM33系列单片机的DataSheet编写&#xff0c;旨在提供一些开发指南。 本文章及本系列其他文章将持续更新&#xff0c;本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期&#xff1a;2024/08/31 文章目录 前言GPIO配置SPI配…

钓鱼特辑(四)安全较量,摆脱“麻瓜”标签

时至今日&#xff0c;尽管员工们对网络安全有所了解&#xff0c;却往往因缺乏足够的安全意识而对攻防没有直观感知。在红队看来&#xff0c;普通员工可能犹如“麻瓜”&#xff0c;防御薄弱&#xff0c;易于突破。 现在红队以求职者或合作方等“人畜无害”的身份在日常沟通中发动…

2024年【广东省安全员C证第四批(专职安全生产管理人员)】新版试题及广东省安全员C证第四批(专职安全生产管理人员)考试试卷

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员C证第四批&#xff08;专职安全生产管理人员&#xff09;新版试题是安全生产模拟考试一点通生成的&#xff0c;广东省安全员C证第四批&#xff08;专职安全生产管理人员&#xff09;证模拟考试题库是根据…

adb大全指令(持续更新)

连接adb adb connect 192.168.1.133(局域网ip)连接调试命令 adb shell打开日志工具 logcat

Shopify接口开发工具shopify-sdk踩坑

背景&#xff1a;   先介绍一下shopify-sdk&#xff0c;它使用java语言开发&#xff0c;是用来做shopify接口二次开发的。做过Shopify独立站的都知道&#xff0c;shopify店铺有管理后台去给管理员增删改查商品和订单等数据&#xff0c;这些数据其实都是可以通过shopify提供的…