QT——自定义控件绘图

一.QPaintEvent绘图事件

QPaintEvent是QT中一个重要的类,专门用于绘图事件。当QT视图组件需要重绘制自己的一部分时,就会产生该事件,通常发生在以下几种情况。

  • 窗口第一次显示时:当窗口或控件第一次出现在屏幕中,系统或窗口就会生成QPaintEvent事件,通知窗口进行自身的绘制
  • 窗口大小改变时:当用户改变窗口的大小时,窗口中的内容通常需要重新绘制以适应新的尺寸
  • 窗口部分被遮挡后又重新显示时:如果窗口被其他窗口遮挡,然后又重新露出来,被遮挡的部分通常需要重新绘制
  • 手动请求重绘:通过调用QWidget的update()或repaint()方法,可以手动触发重绘事件。在Qt应用程序中,通常通过重写QWidget的paintEvent(QPaintEvent*)方法来处理绘制逻辑。

在Qt应用程序中,通常通过重写QWidget的paintEvent(QPaintEvent*)方法来处理绘制逻辑。

二.QPainter画家

2.1绘制基本图形

QPainter是Qt库中用于在屏幕上进行绘画的类。它提供了各种绘制功能,比如画线、画图形、画文本等。

1.初始化QPainter:首先,您需要一个QPaintDevice,比如一个QWidget或QPixmap,然后使用它来初始化QPainter对象。

QPainter painter(this); //假设在QWidget的子类中

2.设置画笔和画刷:您可以设置画笔(用于描边)和画刷(用于填充)的颜色、样式等。

/*QPen pen(Qt::green, 4);
painter.setPen(pen);*/painter.setPen(Qt::blue);                             //设置画笔颜色为蓝色
painter.setBrush(Qt::yellow);                         //设置画刷颜色为黄色(填充色)
painter.setRenderHint(QPainter::Antialiasing, true);  //启用抗锯齿
painter.translate(rect().center()); //移动坐标原点至屏幕中央
painter.route(135);                 //旋转坐标系,正值代表顺时针painter.save();                     //保存当前状态
painter.restore();                  //与save函数配合使用,可恢复绘画师之前的状态

3.绘制图形:使用QPainter的方法来绘制线条、矩形、圆形、文本等。

painter.drawLine(10, 10, 100, 100);         //1.画线
painter.drawLine(QLine(10, 10, 100, 100));
painter.drawLine(QPoint(10, 10), QPoint(100, 100));painter.drawRect(10, 10, 100, 100);         //2.画矩形
painter.drawRect(QRect(10, 10, 100, 100));painter.drawText(10, 10, "Hello, Qt!");     //3.画文本
painter.drawText(QPoint(10,10), "Hello, Qt!");
//在屏幕正中央画文本
painter.drawText(rect().center(), "Hello, Qt!");painter.drawEllipse(QRect(10,10,100,100));  //4.在矩形区域内画圆形或椭圆
painter.drawEllipse(10,10,100,100);
painter.drawEllipse(QPoint(20,30), 80, 80);painter.drawRect(QRect(20,20,200,100));     //5.在矩形区域内画扇形
painter.drawPie(QRect(20,20,200,100), 45*16, 90*16);
painter.drawPie(QRect(20,20,200,100), -45*16, -90*16);
//第二个参数是起始角度,第三个参数是跨度

 QT中是以1/16度为基本单位的,起始角度和跨度同时为正是逆时针绘制,同时为负是顺时针绘制

起始角度:0       跨度:180        起始角度:45      跨度:135      起始角度:0      跨度:360

 

2.2渐变色

1.线性渐变

QLinearGradient是Qt框架中用于创建线性渐变的类。线性渐变是一种从一个颜色平滑过渡到另一个颜色的效果,其变化沿着两个点之间的直线进行。这种渐变在图形用户界面设计中非常常见,用于添加深度、立体感或动态效果。

1. 创建 QLinearGradient 对象:指定渐变的起点和终点坐标。

从左上顶点到右下顶点进行渐变

QLinearGradient gradient(QPointF(10, 10), QPointF(50, 50));

 从左边到右边进行渐变(图形的最左边的中间部分开始到最右边的中间部分结束)

QLinearGradient gradient(QPoint(100,110), QPoint(200, 110));

2. 设置颜色停靠点:在渐变线上定义颜色和相应的位置。可以设置多个颜色停靠点来创建更复杂的渐变效果.

// 设置颜色停靠点:在渐变线上定义颜色和相应的位置
gradient.setColorAt(0.0, Qt::red);    // 起点颜色为红色
gradient.setColorAt(0.5, Qt::green);  // 中间颜色为绿色
gradient.setColorAt(1.0, Qt::blue);   // 终点颜色为蓝色

3. 使用渐变创建一个QPen(边框为渐变色)或QBrush(填充为渐变色),然后绘制图形

QPen pen;
pen.setBrush(gradient);
pen.setWidth(4); // 设置线条宽度
painter.setPen(pen);// 绘制渐变色边框的矩形
painter.drawRect(10, 10, 200, 200);
// 使用渐变创建 QPen
painter.setBrush(gradient);
painter.setPen(Qt::noPen());// 绘制渐变色边框的矩形
painter.drawRect(10, 10, 200, 200);

                  

2.径向渐变

QRadialGradient是Qt框架中用于创建径向渐变的类。径向渐变是一种从中心点向外部辐射的颜色渐变,通常在中心点有一种颜色,而向外围渐渐变化为另一种颜色。这种渐变非常适合用于模拟光源、阴影或创建圆形的立体感。

1.创建QRadialGradient对象:指定渐变的中心点、半径以及焦点(可选)。

2.设置颜色停靠点:在径向渐变中定义颜色和对应的位置。

3.使用渐变创建QBrush:利用QRadialGradient对象创建一个QBrush,然后用它在QPainter中进行绘制。

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); // 启用抗锯齿// 创建对象,设置中心点、半径和焦点(可选)
QRadialGradient gradient(rect().center(), 100);// 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
gradient.setColorAt(0.0, QColor(255, 206, 232));  // 中间颜色淡粉色
gradient.setColorAt(1.0, QColor(255, 155, 170));  // 边缘为深粉色// 使用渐变创建 QBrush
painter.setBrush(gradient);
painter.drawEllipse(rect().center(), 100, 100);  // 绘制圆形

3.圆锥形渐变

QConicalGradient是Qt框架中用于创建圆锥形渐变的类。圆锥渐变是一种渐变效果,其中颜色沿着圆锥的轮廓变化,类似于旋转颜色轮。这种渐变以其中心点为基点,颜色沿圆周分布,可以创建出富有动感的视觉效果。

在使用时,角度是按照顺时针方向测量的,起始点(0度)通常在三点钟方向。QConicalGradient非常适合用于创建旋转或动态效果的图形,例如加载指示器、进度条或任何需要圆周颜色变化的场景。

1. 创建 QConicalGradient 对象: 指定渐变的中心点和起始角度。

2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。

3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); // 启用抗锯齿// 1. 创建 QConicalGradient 对象:指定渐变的中心点和起始角度。
QConicalGradient gradient(width() / 2, height() / 2, 0);// 2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。
gradient.setColorAt(0.0, QColor(255, 182, 193));    // 中心颜色为浅粉色
gradient.setColorAt(0.5, QColor(255, 160, 122));    // 中间颜色为浅橙色
gradient.setColorAt(1.0, QColor(173, 216, 230));    // 边缘颜色为浅蓝色
// 3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。
painter.setBrush(gradient);
painter.drawEllipse(rect());                        // 绘制圆形

      

三.实现仿雷达扫描

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QRadialGradient>
#include <QPainter>
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QTimer *timer = new QTimer(this);timer->setInterval(10);                                 //设置定时时间为10msconnect(timer, &QTimer::timeout, this, [=](){           //当定时器超时时,激活绘画事件update();});timer->start();                                         //启动定时器
}void Widget::paintEvent(QPaintEvent *event)
{static int t = 0;                                       //初始角度为0度if(t == 360){t = 0;}QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);     //启用抗锯齿QBrush brush(Qt::black);painter.setBrush(brush);                                 //设置画刷为黑色painter.drawRect(rect());                                //画矩形(黑色背景)painter.translate(rect().center());                      //将坐标移动到屏幕正中央QPen pen(Qt::green, 4);painter.setPen(pen);                                     //设置画笔颜色为绿色painter.setBrush(Qt::NoBrush);                           //丢掉画刷int R = height()/2/7;                                    //圆的半径for(int i = 1; i <= 7; i++){                             //画圆painter.drawEllipse(QPoint(0, 0), R*i, R*i);}painter.drawLine(QPoint(-R*7,0), QPoint(R*7,0));         //画横线painter.drawLine(QPoint(0,-R*7), QPoint(0,R*7));         //画竖线//设置锥形渐变// 1. 创建 QConicalGradient 对象:指定渐变的中心点和起始角度。QConicalGradient gradient(0, 0, t);// 2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。gradient.setColorAt(0.0, QColor(0, 255, 0, 200));gradient.setColorAt(0.1, QColor(0, 255, 0, 100));gradient.setColorAt(0.2, QColor(0, 255, 0, 0));gradient.setColorAt(1, QColor(0, 255, 0, 0));// 3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。painter.setBrush(gradient);painter.setPen(Qt::NoPen);painter.drawPie(QRect(-R*7,-R*7,R*2*7,R*2*7), t*16, 70*16); //画扇形t += 1;
}Widget::~Widget()
{delete ui;
}

四.实现简易的汽车仪表盘

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QRadialGradient>
#include <QPainter>
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QTimer *timer = new QTimer(this);timer->setInterval(50);                                 //设置定时时间为10msconnect(timer, &QTimer::timeout, this, [=](){           //当定时器超时时,激活绘画事件update();});timer->start();                                         //启动定时器
}void Widget::paintEvent(QPaintEvent *event)
{static int anc = 0;if(anc == 270){t = 1;}else if(anc == 0){t = 0;}QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);     // 启用抗锯齿QBrush brush(Qt::black);painter.setBrush(brush);                                 // 设置画刷为黑色painter.drawRect(rect());                                // (1)画矩形(黑色背景)painter.translate(rect().center());                      // 将坐标原点移动到屏幕正中央painter.setPen(Qt::NoPen);int bigR = height()/2;                                   // 外圆的半径为高度的一半//设置径向渐变QRadialGradient gradient(QPoint(0,0), bigR);// 设置颜色停靠点:在径向渐变中定义颜色和对应的位置gradient.setColorAt(0.0, QColor(255, 0, 0, 100));gradient.setColorAt(1.0, QColor(255, 0, 0, 200));// 使用渐变创建 QBrushpainter.setBrush(gradient);painter.drawEllipse(QPoint(0,0), bigR, bigR);            // (2)绘制外部圆形painter.setBrush(Qt::NoBrush);QPen pen(Qt::white, 4);painter.setPen(pen);painter.drawEllipse(QPoint(0,0), 60, 60);                // (3)绘制内部圆形//最小刻度double angle = 270*1.0/50;//保存当前painter属性painter.save();painter.rotate(135);                                     // 坐标系顺时针旋转135度(90度+45度)for(int i = 0; i <= 50; i++){                            // (4)绘制刻度和数字if(i % 10 == 0){//左半部分的仪表盘上的数字需要将坐标轴翻转180度后显示(02变为20)if(i * angle <= 135){painter.drawLine(QPoint(bigR-30, 0), QPoint(bigR-3, 0));painter.rotate(180);painter.drawText(QPoint(-(bigR - 32), 5),QString::number(i));painter.rotate(-180);}else{painter.drawLine(QPoint(bigR-30, 0), QPoint(bigR-3, 0));painter.drawText(QPoint(bigR - 50, 5),QString::number(i));}}else{painter.drawLine(QPoint(bigR-20, 0), QPoint(bigR-3, 0));}if(i <= 49){painter.rotate(angle);}}//注意:此时的坐标轴x轴在50刻度位置//坐标系旋转回初始位置painter.restore();painter.rotate(135 + anc);painter.setPen(QPen(Qt::yellow, 4));//(5)画指针painter.drawLine(QPoint(60,0), QPoint(bigR-70, 0));//坐标系旋转回到135度painter.rotate(-anc);//此时坐标在135度位置painter.setBrush(QColor(85,0,255,100));painter.setPen(Qt::NoPen);//(6)画扇形,扇形起始角度始终为135度,跨度为0到270度painter.drawPie(QRect(-bigR+70,-bigR+70,bigR*2-140,bigR*2-140), 0, -anc*16);if(t == 0){anc += 2;}else{anc -= 2;}}Widget::~Widget()
{delete ui;
}

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

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

相关文章

Java项目实战II基于Java+Spring Boot+MySQL的高校办公室行政事务管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在高等教育…

非计算机背景但是想从事医学AI研究,需要掌握的编程语言|个人观点·24-11-08

小罗碎碎念 目前&#xff0c;我们从事医学AI研究的&#xff0c;接触的最多的两种编程语言应该就是R和Python了。那么初学者很容易提出一个疑问&#xff0c;**我想从事医学AI相关的研究的话&#xff0c;应该学哪些编程语言呢&#xff1f;**在文章的开头&#xff0c;我可以先给出…

arkUI:Flex弹性布局的各个属性

arkUI&#xff1a;Flex弹性布局的简单使用 1 主要内容说明2 相关内容2.1 Flex弹性布局的方向2.1.1 源码1的简答说明2.1.2 源码1 &#xff08;Flex弹性布局的方向&#xff09;2.1.3 源码1运行效果2.1.3.1 当direction: FlexDirection.RowReverse2.1.3.2 当direction: FlexDirect…

高效Web测试:构建Pytest、Allure和Jenkins的自动化测试生态

Pytest介绍 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个特点&#xff1a;简单灵活、容易上手、文档丰富&#xff1b;支持参数化&#xff0c;可以细粒度地控制被测用例&#xff1b;能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来…

ros入门:topic话题通信(c++)

准备工作 创建工作空间 mkdir -p demo02_pub/src/ 生成依赖文件 cd demo02_pub/ catkin_make 进入src目录执行 catkin_create_pkg ros_pub_sub/ roscpp rospy std__msgs 发布者实现 消息发布代码编写 cd demo02_pub/src/ros_pub_sub/src 创建代码文件demo01_pub.cc …

重建大师7.0 | 质效全面提升,塑造更优质的实景三维重建

在大势智慧“AI智算、国产信创”2024秋季新品发布会上&#xff0c;重建大师7.0版以其卓越性能惊艳登场。这一新版本不仅引入了创新的倾斜高斯泼溅方法&#xff08;OPGS&#xff09;&#xff0c;实现城市级场景的高效三维重建。 针对传统倾斜建模方法&#xff0c;重建大师7.0同…

Unity性能优化5【物理篇】

1.刚体的碰撞检测属性首选离散型 离散碰撞的缺点是小物体快速移动时&#xff0c;有丢失碰撞的风险。此下拉菜单中&#xff0c;越下面的选项碰撞检测频率越高&#xff0c;性能消耗也显著增加。因此在选择碰撞检测类型时尽量选择离散型。 2.优化碰撞矩阵 合理标记碰撞矩阵可以减…

【threejs】创建及管理场景内的后期处理效果(以bloom为例,开箱即用)

场景内使用 //创建后期通道this.effectManager new EffectManager({ renderer, camera, scene, dom })//循环渲染// 动画----------effect为我控制后期特效的开关animate() {requestAnimationFrame(this.animate);let { camera, controls, effectManager, effect } thisif (!…

建立用邻接表表示的无向图

创建一个建立用邻接表表示的无向图 #include<stdio.h> #include<stdlib.h> typedef struct node {int adjvex;struct node *next; }Anode; typedef struct {char vertex;Anode *link; }Unode; typedef struct {Unode adjlist[100];int vexnum,arcnum; }Adjgraph; …

芯片需要按一下keyup或者复位按键虚拟或者下载之后芯片能下载却运行不了或者需要额外供电。

这些问题很有可能是因为外围电路器件幅值与设计不同的存在&#xff0c;导致你需要外部供电才能实现一个正常运行&#xff0c;可以检查一下外围电路在供电区域的电流区&#xff0c;电阻幅值是否和原理图设计时看的一模一样或者直接更换 因为按键会失灵&#xff0c;首先检查复位按…

Java直播系统视频聊天系统小程序源码

直播视频聊天系统✨&#xff1a;打造你的专属互动空间 &#x1f680; 引言&#xff1a;直播视频聊天系统的兴起 在这个快节奏的数字时代&#xff0c;直播和视频聊天已成为我们日常沟通的重要工具。从游戏直播到在线教育&#xff0c;从远程办公到家庭聚会&#xff0c;直播视频…

云轴科技ZStack助力新远科技开启化工行业智能制造新篇章

新远科技基于云轴科技ZStack Cube超融合和ZStack Zaku容器云平台打造了灵活高效的IT基础设施&#xff0c;实现了IaaS和PaaS层的全面覆盖&#xff0c;优化了资源利用率&#xff0c;降低了硬件成本和运维复杂性&#xff0c;同时强化了数据安全和业务连续性。 化工行业的数字化先…

软件测试PO模式

V1&#xff1a;不使用任何设计模式和单元测试框架 V2&#xff1a;使用UnitTest管理用例 V3&#xff1a;使用方法封装的思想&#xff0c;对代码进行优化 V4&#xff1a;采用PO模式的分层思想对代码进行拆分 V5&#xff1a;对PO分层之后的代码继续优化 V6&#xff1a;PO模式深入封…

网页版五子棋——匹配模块(客户端开发)

前一篇文章&#xff1a;网页版五子棋——用户模块&#xff08;客户端开发&#xff09;-CSDN博客 目录 前言 一、前后端交互接口设计 二、游戏大厅页面 1.页面代码编写 2.前后端交互代码编写 3.测试获取用户信息功能 结尾 前言 前面文章介绍完了五子棋项目用户模块的代码…

Spring设计模式

设计模式 是一种软件开发中的解决方案&#xff0c;设计原则。目的是使代码具有扩展性&#xff0c;可维护性&#xff0c;可读性&#xff0c;如&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09; Spring IoC 容器默认会将 Bean 创建为单例&#xff0c;保证一个类…

【设计模式】结构型模式(一):适配器模式、装饰器模式

结构型模式&#xff08;一&#xff09;&#xff1a;适配器模式、装饰器模式 1.适配器模式&#xff08;Adapter&#xff09;2.装饰器模式&#xff08;Decorator&#xff09;2.1 主要特点2.2 组成部分2.3 示例代码2.3.1 Component 组件2.3.2 ConcreteComponent 具体组件2.3.3 Dec…

Go Energy 跨平台(GUI)应用编译和安装包制作

构建打包 energy cli 平台介绍描述windowNSIS安装包制作工具可通过 energy cli 安装linuxdpkg 命令系统自带macosenergy 仅生成 xxx.app系统自带 安装包制作 config/energy_[os].json是初始化应用时自动生成的应用配置文件&#xff0c;在编译和制作应用安装包时使用 Windows…

【Linux】进程信号全攻略(二)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 再谈信号的捕捉 &#x1f98b; 关于信号捕捉的细节部分&#xff08;sigaction函数&#xff09; 二&#xff1a;&#x1f525; 穿插话题 - 操作系统是怎么运…

鸿蒙的进击之路

1. 题记&#xff1a; 为什么要写鸿蒙&#xff0c;因为她是华为的&#xff0c;为什么是华为就要写&#xff0c;因为华为背负了国人太多太多的包袱&#xff0c;或点赞或抨击。 我是强烈支持华为的&#xff0c;但我会客观公正地去评价华为的产品&#xff0c;就比如这篇博文&#…

Swagger的介绍和使用方式+常用注解

介绍: 使用Swagger你只需要按照它的规范去定义接口及接口相关的信息&#xff0c;就可以做到生成接口文档&#xff0c;以及在线接口调试页面.简单来说就是我们只需要知道使用Swagger可以帮助我们后端生成接口文档 Swagger官网:https://swagger.io/ 因为单独使用Swagger会有些…