Qt编写自定义控件:遥控器圆形按钮控件

2023-11-06

根据QT图形视图框架:自定义遥控器圆形按钮图形项改的QWidget版本,原理一样。

效果:

代码:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
signals:
    void selectColor(QString colorString);
protected:
    void paintEvent(QPaintEvent *event)override;
    void mousePressEvent(QMouseEvent *event)override;
    void mouseReleaseEvent(QMouseEvent* event)override;
private:
    Ui::Widget *ui;
    bool isPointInCir(const QPoint &point, const QRect &rect);
    QRectF drawRect;//整个大圆的范围
    QPainterPath fanShaped[4];
    QRectF centerCircularRect;//中心圆按钮的范围
    QPainterPath gradientArc(double startAngle, double angleLength, double arcHeight);
    enum class pressBtnType //按下的是哪个按钮
    {
        up = 0,
        left,
        down,
        right,
        center,
        None
    };
    pressBtnType pressedBtn{pressBtnType::None};
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QMouseEvent>
#include <math.h>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        QPoint point = event->pos();
        if(isPointInCir(point,drawRect.toRect()))
        {
            if(isPointInCir(point,centerCircularRect.toRect()))
            {
                pressedBtn = pressBtnType::center;
            }
            else
            {
                QPoint centerPoint = drawRect.toRect().center();
                double angle = atan2(point.y()-centerPoint.y(),point.x()-centerPoint.x()); //两点之间的角度(弧度)
                angle = -angle*(180 / 3.1415926); //0°~180° - -180°~0°
                if(angle < 0.0)
                {
                    angle = 360.0 - abs(angle);
                }
                if(angle < 45.0 || angle > 315.0)
                {
                    pressedBtn = pressBtnType::right;
                }
                else if(angle >= 45.0 && angle < 135.0)
                {
                    pressedBtn = pressBtnType::up;
                }
                else if(angle >= 135.0 && angle < 225.0)
                {
                    pressedBtn = pressBtnType::left;
                }
                else if(angle >= 225.0 && angle < 315.0)
                {
                    pressedBtn = pressBtnType::down;
                }
            }
            update();
        }
    }
    return QWidget::mousePressEvent(event);
}

void Widget::mouseReleaseEvent(QMouseEvent* event)
{
    if(pressedBtn != pressBtnType::None)
    {
        pressedBtn = pressBtnType::None;
        update();
    }
    return QWidget::mouseReleaseEvent(event);
}

QPainterPath Widget::gradientArc(double startAngle, double angleLength, double arcHeight)
{
    QPainterPath path;
    path.moveTo(drawRect.center());
    path.arcTo(drawRect, startAngle, angleLength);

    QPainterPath subPath;
    subPath.addEllipse(drawRect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));

    // path为扇形 subPath为椭圆
    path -= subPath;
    return path;
}

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setPen(Qt::NoPen);

    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform,true);

    QPoint centerPoint = rect().center();

    painter.save();
    painter.setPen(QColor("#222222"));
    painter.setBrush(QColor("#EAEAEA"));
    double radius = (std::min(width(),height()) - 10 * 2 ) / 2;
    drawRect = QRectF(centerPoint.x()-radius, centerPoint.y()-radius, radius*2, radius*2);
    double arcHeight = radius / 2;

    fanShaped[0] = gradientArc(45.0,  90.0, arcHeight);//上
    fanShaped[1] = gradientArc(135.0, 90.0, arcHeight);//左
    fanShaped[2] = gradientArc(225.0, 90.0, arcHeight);//下
    fanShaped[3] = gradientArc(315.0, 90.0, arcHeight);//右

    for (int i = 0;i < 4;++i)
    {
        painter.drawPath(fanShaped[i]);
    }
    painter.restore();

    centerCircularRect = QRectF(centerPoint.x() - (radius / 2), centerPoint.y() - (radius / 2), radius, radius).adjusted(2,2,-2,-2);
    painter.save();
    painter.setPen(Qt::transparent);
    painter.setBrush(QColor("#EAEAEA"));
    painter.drawEllipse(centerCircularRect);
    painter.restore();

    //绘制文字
    //左
    painter.save();
    QRectF textRect = QRectF(drawRect.x(),centerCircularRect.y(),radius / 2,radius);
    QPen p(Qt::SolidLine);
    p.setColor("#000000");
    p.setWidth(2);
    painter.setPen(p);
    QFont font = painter.font();
    font.setPixelSize(24);
    painter.setFont(font);
    painter.drawText(textRect, Qt::AlignCenter, "〈");//在此区域的中间位置绘制文字 〉

    //上
    textRect = QRectF(centerCircularRect.x(),drawRect.y(),radius,radius / 2);
    painter.drawText(textRect, Qt::AlignCenter, "︿");

    //右
    textRect = QRectF(centerCircularRect.topRight().x(),centerCircularRect.topRight().y(),radius / 2,radius);
    painter.drawText(textRect, Qt::AlignCenter, "〉");

    //下
    textRect = QRectF(centerCircularRect.bottomLeft().x(),centerCircularRect.bottomLeft().y(),radius,radius / 2);
    painter.drawText(textRect, Qt::AlignCenter, "﹀");

    painter.drawText(centerCircularRect, Qt::AlignCenter, "OK");
    painter.restore();

    if(pressedBtn != pressBtnType::None)
    {
        painter.save();
        QColor slightlyOpaqueBlack(0, 0, 0, 63);
        painter.setBrush(slightlyOpaqueBlack);
        painter.setPen(Qt::transparent);
        if(pressedBtn == pressBtnType::center)
        {
            painter.drawEllipse(centerCircularRect);
        }
        else
        {
            int index = -1;
            index = static_cast<int>(pressedBtn);
            if(index >= 0)
            {
                painter.drawPath(fanShaped[index]);
            }
        }
        painter.restore();
    }

    painter.restore();
}

bool Widget::isPointInCir(const QPoint &point,const QRect & rect)//判断点是否在圆范围内
{
    const QPoint & centerPoint = rect.center();
    int x = point.x() - centerPoint.x();
    int y = point.y() - centerPoint.y();
    if(sqrt(pow(x,2) + pow(y,2)) <= static_cast<double>(rect.width() / 2))
    {
        return true;
    }
    return false;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt编写自定义控件:遥控器圆形按钮控件 的相关文章

  • Flash Linux to eMMC

    实验目的 从eMMC启动Linux系统 Step1 确定eMMC被挂在哪个设备 哪个设备含有boot0分区和boot1分区 就是eMMC 实验中是位于mmcblk1上 root am64xx evm ls l dev mmcblk brw
  • QT入门Input Widgets之QScrollBar

    目录 一 界面布局功能 1 界面位置介绍 2 控件界面基本属性 2 1 horizontalScrollBar界面属性 3 样式设置 此文为作者原创 创作不易 转载请标明出处 一 界面布局功能 1 界面位置介绍 QScrollBar主要分为
  • Python使用Matplotlib可视化多组并排的柱状图

    Python使用Matplotlib可视化多组并排的柱状图 Matplotlib是Python中最流行的数据可视化库之一 它可以创建各种类型的图表 包括线性图 散点图 饼图等等 在本文中 我们将重点介绍如何使用Matplotlib库创建多组
  • CyclicBarrier调试

    一CyclicBarrier 控制所有线程等待 知道达到某种条件 所有的线程才会继续走下去 是一个同步工具类 它允许一组线程互相等待 直到到达某个公共屏障点才停止等待 与CountDownLatch不同的是该barrier 屏障 在释放等待
  • 在vw中运行linux,Windows系统直接运行Linux,竟是如此简单

    要想在Windows10以前的系统上 运行Linux程序是比较复杂的 需要使用cygwin之类的工具 不仅下载慢 而且功能有限 后来出现了诸如VirtualBox VMWare Workstation和Microsoft Hyper V之类
  • 使用python随机生成IP+域名并写入excel表

    题目要求 使用python随机生成IP 随机域名 并创建excel表 将生成的随机IP与域名数据写入 代码如下 import random import socket import struct import xlwt book xlwt
  • Window 安装Hive

    基本环境资源 Hadoop 2 7 X Hive 2 1 X bin tar gz 版本 Hive 1 x src tar gz 源码版本 第一步 windows 安装Hadoop2 7 x 请参考 第二步 下载Hive tar gz 官网
  • ASP.NET Core 企业级开发架构简介及框架汇总

    ASP NET Core 企业开发架构概述 企业开发框架包括垂直方向架构和水平方向架构 垂直方向架构是指一个应用程序的由下到上叠加多层的架构 同时这样的程序又叫整体式程序 水平方向架构是指将大应用分成若干小的应用实现系统功能的架构 同时这样
  • VScode连接本地Docker

    一 安装VScode和Docker 1 vscode的安装 官网下载到最新的X64安装包 然后使用下述命令进行安装 dpkg i code 1 73 1 1667967334 amd64 deb 安装成功之后 可以在应用的安装列表中查看到
  • OpenHarmony学习笔记——Hi3861使用DHT11获取温湿度

    文章目录 前言 DHT11简介 通信流程 硬件连接 编程实现 GPIO API简介 复位总线 DHT11应答 数据读取 效果一览 总结 目录 前言 此文主要是使用Hi3861的GPIO口 模拟1 Wire时序 获取类单总线协议器件DHT11
  • 2023中国人工智能成熟度模型报告

    本报告基于三大关键指标 参考市场规模 融资事件等公开资料 并结合了AI行业内硬件 模型 应用不同领域的各位专家观点 构建涵盖40 技术点的中国人工智能成熟度模型 为技术的应用决策和未来投资参考提供研究分析工具 关注公众号 互联互通社区 回复
  • xp系统itunes无法连接服务器失败,xp系统iTunes无法连接到iTunes store的修复步骤

    今天和大家分享一下xp系统iTunes无法连接到iTunes store问题的解决方法 在使用xp系统的过程中经常不知道如何去解决xp系统iTunes无法连接到iTunes store的问题 有什么好的办法去解决xp系统iTunes无法连接
  • NoSQL数据库入门

    一 NoSQL数据库概述 NoSQL 是一种不同于关系数据库的数据库管理系统设计方式 是对非关系型数据库的统称 它所采用的数据模型并非传统关系数据库的关系模型 而是类似键 值 列族 文档等非关系模型 NoSQL 数据库没有固定的表结构 通常
  • java截取某两个字符之间的字串_Java截取特定两个标记之间的字符串实例

    Java截取特定两个标记之间的字符串实例 如有一串字符串 higklmnopq java代码如下 public class StringTest public static void main String args String str
  • linux 下安装编译配置 QT

    注 1 自己 make qt everywhere opensource src s时 在 configure前主动装好下面3个 sudo apt get install libX11 dev libXext dev libXtst dev
  • 声灭火器火灾数据集-Acoustic Extinguisher Fire Dataset

    Acoustic Extinguisher Fire Dataset The dataset was obtained as a result of the extinguishing tests of four different fue
  • FFmpeg 的介绍与使用

    FFmpeg Fast Forward Moving Picture Experts Group FFmpeg 命令行工具的使用 在 FFmpeg 官网 可以下载对应平台的可执行程序包 比如 Windows 平台的下载地址是 https f
  • c语言 统计字符出现次数

    本题要求编写程序 统计并输出某给定字符在给定字符串中出现的次数 输入格式 输入第一行给出一个以回车结束的字符串 少于80个字符 第二行输入一个字符 输出格式 在一行中输出给定字符在给定字符串中出现的次数 我的答案 include

随机推荐

  • E1,T1的用途和区别

    T1在北美等国家使用 1 548M 24channels E1在欧洲和中国等大部分国家使用 2 048M 32channels 都是TDM的东西 一般是做语音使用 E1 T1说白了只是传输标准 真正承载什么业务其实没有太大关系E1 2 04
  • pytorch实现Deep_Residual_network,resnet源码解读

    今天带大家学习resnet网络系列 resnet的发展与思考 任何一篇网络的理解不应该单单局限在一篇或几篇博客上 复制别人的代码 不追根溯源是很难有深度的理解 所以今天 我整理这篇博客带大家从头到位看resnet为什么有用 理论层面 怎么实
  • electorn更换窗口图标

    在用electron开发桌面端的时候 打包成exe文件 需要更改默认的图标 具体做法 在根目录新建新建存放icon图标的目录 需要两个icon icon icns icon ico 注意 1 这两个图标大小不能256 256 2 不能直接用
  • 怎么把name一样的多个字段传到后台_泛微OA E8流程小技巧(01)-- 字段联动(后台)...

    大家好 我是响指不够响 前面我介绍了OA一个很实用的功能 字段联动 通过它我们可以让系统自动带出一些相关信息不需要我们自己一项项的去查找 如果大家感兴趣的话 请移步到泛微OA E8流程小技巧 01 字段联动 前台 查阅 图1 那么这个功能我
  • Proxifier逆向分析(Mac)

    简介 Proxifier是一款功能非常强大的socks5客户端 可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链 概念 支持 64位系统 支持Xp Vista Win7 MAC OS 支持socks4 soc
  • OpenCV-Python实战(12)——一文详解AR增强现实

    OpenCV Python实战 12 一文详解AR增强现实 0 前言 1 增强现实简介 2 基于无标记的增强现实 2 1 特征检测 2 2 特征匹配 2 3 利用特征匹配和单应性计算以查找对象 3 基于标记的增强现实 3 1 创建标记和字典
  • 史上最全的测试用例

    目录 一 文本框为字符型 二 文本框为数值型 三 文本框为日期型 四 文本框为时间型 一 文本框为字符型 必填项非空校验 1 必填项未输入 程序应提示错误 2 必填项只输入若干个空格 未输入其它字符 程序应提示错误 字段唯一性校验 不是所有
  • CentOS使用yum安装最新版nginx步骤

    目录 安装依赖 配置yum 源文件 yum 安装nginx 配置开机启动 启动 停止 重载 查看nginx的状态及进程与端口 启动后 杀掉进程命令 查看版本 server配置说明 负载均衡配置 安装依赖 sudo yum install y
  • Sweet32漏洞,升级openssl或者禁用3DES和DES弱加密算法

    问题 由于等保的原因 被服务商扫描出漏洞 warnings 64 bit block cipher 3DES vulnerable to SWEET32 attack 漏洞复现 nmap sV script ssl enum ciphers
  • 机器人爱因斯坦、索菲亚对话人类:“人类必须自我修复”

    人工智能的发展速度真的太快了 就在不久前机器人 索菲亚 获得沙特阿拉伯获得了公民身份之后 机器人版的爱因斯坦教授也登上了历史的舞台 机器人版的爱因斯坦教授是由汉森机器人 Hanson Robotics 公司制造的 这家机器人制造商制造的另外
  • 计算机软件的本质是什么,程序员的本质是什么

    问题本质 首先回归到问题本身 程序员十年后还会有今天的收入吗 假如今天的收入代表比较值钱的话 这个问题其实可以换一种等同的问法 即 程序员十年后还会像现在这么值钱吗 十年这里可以一定程度的用未来来代替 那么我们接着对问题进行等同转换 程序员
  • 开源机器人自学指南

    雷锋网 公众号 雷锋网 AI科技评论按 本文转载自公众号Nao 作者邱强 AI 科技评论已获授权 我在Github上发起了一个开源机器人学自学指南 地址是 https github com qqfly how to learn roboti
  • php每天扒取当天新闻_thinkphp5使用workerman定时器定时爬取某站点新闻资讯等内容...

    1 首先通过 composer 安装workerman 在thinkphp5完全开发手册的扩展 coposer包 workerman有详细说明 在项目根目录执行以下指令 composer require topthink think wor
  • Scala基础学习之运算符

    章节目标 理解运算符的相关概述 掌握算术 赋值 关系 逻辑运算符的用法 掌握交换变量案例 理解位运算符的用法 1 算术运算符 1 1 运算符简介 用来拼接变量或者常量的符号就叫 运算符 而通过运算符连接起来的式子就叫 表达式 实际开发中 我
  • 论文阅读方法

    一 先看综述 先读综述 可以更好地认识课题 知道已经做出什么 自己要做什么 还有什么问题没有解决 对于国内文献一般批评的声音很多 但它是你迅速了解你的研究领域的入口 在此之后 你再看外文文献会比一开始直接看外文文献理解的快得多 而国外的综述
  • 算法与数据结构_栈

    栈 一 什么是栈 特点总结为先进后出 后进先出 就是 First In Last Out FILO 这就是典型的 栈 结构 从其操作特性来看 栈是一种 操作受限 的线性表 它只允许从一端进行数据的插入与移除 二 既然栈不如链表 数组灵活 为
  • webdriver之获取cookie 转化成字典或者string的方法

    转字典 for i in cookieJs cookie server setdefault i get name i get value print cookie server 转string cookie item name item
  • STM32CubeMX学习一 之GPIO配置

    文章目录 前言 一 本地环境 二 开始 1 工程创建 2 GPIO配置 2 时钟配置 3 代码生成 3 编译工程 前言 记录一下STM32CubeMX的学习笔记 同时分享给初学的小白 希望一起进步 一 本地环境 编译环境 KEIL 代码生成
  • Qt正则表达式

    正则表达式 正则表达式即一个文本匹配字符串的一种模式 Qt中QRegExp类实现使用正则表达式进行模式匹配 且完全支持Unicode 主要应用 字符串验证 搜索 查找替换 分割 正则表达式中字符及字符集 正则表达式中的量词 正则表达式中的断
  • Qt编写自定义控件:遥控器圆形按钮控件

    根据QT图形视图框架 自定义遥控器圆形按钮图形项改的QWidget版本 原理一样 效果 代码 ifndef WIDGET H define WIDGET H include