Qt 自定义控件(Qt绘图)

news2025/1/11 15:44:20

一、QPaintEvent绘图事件
1、QPaintEvent是Qt框架中一个重要的事件类,专门用于处理绘图事件。


2、当Qt视图组件需要重绘自己的一部分时,就会产生QPaintEvent事件。


3、Qt视图组件重绘自己,通常发生在以下情况:
  (1)、窗口第一次显示时: 当窗口或控件第一次出现在屏幕上时,系统会生成一个QPaintEvent事件,通知窗口进行自身的绘制。
  (2)、窗口大小改变时: 当用户改变窗口的大小时,窗口的内容通常需要重新绘制以适应新的尺寸。
  (3)、窗口部分被遮挡后又重新显示时: 如果窗口被其他窗口遮挡,然后又重新露出来,被遮挡的部分通常需要重新绘制。
  (4)、手动请求重绘: 通过调用QWidget的update()或repaint()方法,可以手动触发重绘事件。
  (5)、还有很多其它情况,也会重绘自己。


4、QWidget的update()和repaint()的主要区别:
  (1)、执行时机:
     * update():将一个QPaintEvent添加到事件队列中,等待稍后执行,它不会立即执行paintEvent()。
     * repaint():会立即执行paintEvent(),不会等待事件队列的处理。
  (2)、重绘区域:
     * update():可以合并多个重绘请求,只在最后执行一次paintEvent(),可以减少不必要的重绘操作,提高性能。
     * repaint():每次调用都会触发一次paintEvent(),不进行任何合并操作。
  (3)、同步性:
     * update():是异步的。
     * repaint():是同步的。
  (4)、使用场景:
     * update():通常用于在不重要的时候触发重绘,如用户交互、动画等,它允许Qt进行优化,减少闪烁现象。
     * repaint():适用于需要立即反馈的场景,如在paintEvent中计算和显示一些重要的信息。


5、在Qt应用程序中,通常通过重写QWidget的paintEvent()方法来处理绘制逻辑。
  (1)、重写paintEvent是在Qt中自定义绘制的标准做法。 例如:

      class MyWidget : public QWidget {
      protected:
          void paintEvent(QPaintEvent * event) override {
              QPainter painter(this);
              //绘制逻辑
          }
      };


6、在paintEvent()中,可以创建一个QPainter对象并使用它来执行绘制操作。
  (1)、QPainter可以绘制各种基本图形,如线条、矩形、椭圆等,还可以绘制文本和图像。
  


二、QPainter画家
  1、概述
     (1)、QPainter是Qt库中进行绘画的类,它提供了各种绘制功能,比如画文本、画线、画图形等。
     (2)、QPainter基本用法:
         * 初始化QPainter: 用一个QPaintDevice,比如QWidget、QPixmap、QImage等,初始化QPainter对象。
           QPainter painter(this);   //假设在QWidget的子类中, this指向QWidget子类对象
         * 设置画笔和画刷: 可以设置画笔(用于描边)和画刷(用于填充)的颜色、样式等。
           painter.setPen(Qt::blue);     //设置画笔颜色为蓝色
           painter.setBrush(Qt::yellow); //设置画刷颜色为黄色
         * 绘制图形: 使用QPainter的drawXXX()方法来绘制线条、矩形、圆形、文本等。
           painter.drawLine(10, 10, 100, 100);    //画线
           painter.drawRect(10, 10, 100, 100);    //画矩形
           painter.drawText(10, 10, "Hello Qt!"); //画文本
     (3)、QPainter的使用依赖于Qt的事件循环,因此通常在QWidget的paintEvent()或类似的事件处理函数中使用它。


  2、QPainter画文字
     (1)、画文字API使用:

  void Widget::paintEvent(QPaintEvent * event)
  {
      QPainter painter(this);
      painter.setPen(Qt::blue);
      painter.setFont(QFont("Arial", 20));
             
      painter.drawRect(50, 50, 200, 100);
             
      //指定文字的左下角点。
      painter.drawText(50, 50, "Hello");
      painter.drawText(QPoint(50, 50), "Hello");
      //文字贴在矩形的左上角点,在矩形内显示。
      painter.drawText(QRect(50, 50, 200, 100), "Hello");
      //在矩形内,指定flags,显示文字
      painter.drawText(50, 50, 200, 100, Qt::AlignHCenter | Qt::AlignVCenter, "Hello");
      painter.drawText(QRect(50, 50, 200, 100), Qt::AlignHCenter | Qt::AlignVCenter, "Hello");
   }


  3、QPainter画线、画矩形、画椭圆
      (1)、画线API使用:

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

        //两个点确定一条线
        painter.drawLine(100, 300, 300, 100);
        painter.drawLine(QPoint(100, 320), QPoint(300, 120));
        painter.drawLine(QLine(100, 340, 300, 140));
   }


      (2)、画矩形API使用:

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

     //左上角点、长、宽确定一个矩形
     painter.drawRect(30, 30, 200, 100);
     painter.drawRect(QRect(200, 200, 200, 100));
}


      (3)、画椭圆API使用:

 void Widget::paintEvent(QPaintEvent * event)
 {
      QPainter painter(this);
      painter.setPen(Qt::blue);
              
      //在矩形里,贴着矩形的边,画椭圆。
      painter.drawEllipse(QRect(50, 50, 200, 100));
      //(50,50)是矩形左上角点,200是矩形的长,100是矩形的宽。
      painter.drawEllipse(50, 50, 200, 100);
      //指定椭圆的中心点center,椭圆的半径长rx,椭圆的半径宽ry,画椭圆。
      painter.drawEllipse(rect().center(), 100, 50);
 }


  4、QPainter画弧、画扇形
      (1)、画圆弧:
          * 圆弧是椭圆的一部分,所以由绘制椭圆的参数,再加一个起始角、伸缩角,就可以定义圆弧。
          * 绘制圆弧由给定矩形、起始角startAngle、伸缩角spanAngle定义。
          * 起始角和伸缩角必须以1/16度指定,即一个完整的圆等于5760(16 * 360°),最小单位是1/16度。
          * 角度的正值表示逆时针方向,负值表示顺时针方向。
          * 零度在3点钟方位。
          * 画圆弧API使用:

  void Widget::paintEvent(QPaintEvent * event)
  {
       QPainter painter(this);
       painter.setPen(Qt::blue);
       painter.setFont(QFont("Arial", 20));

       QRect rect(50, 50, 200, 100);
       painter.drawRect(rect);
       painter.drawArc(rect, 30*16, 120*16);
       painter.drawArc(50, 50, 200, 100, -30*16, -120*16);
 }


      (2)、画扇形:
          * 画扇形和画弧的参数是一样的,弧是扇形的最外层部分。
          * 画扇形API使用:

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

      QRect rect(50, 50, 200, 100);
      painter.drawPie(rect, 30 * 16, 120 * 16);
      painter.drawPie(200, 200, 200, 200, 45*16, 90*16);
  }


  5、渐变色
      (1)、线性渐变
          * QLinearGradient是Qt框架中用于创建线性渐变的类。
          * 线性渐变是一种从一个颜色平滑过渡到另一个颜色的效果,其变化沿着两个点之间的直线进行。
          * 这种渐变在图形用户界面设计中非常常见,用于添加深度、立体感或动态效果。
          * 基本用法:
            -> 创建QLinearGradient对象: 指定渐变的起点和终点坐标。
            -> 设置颜色停靠点: 在渐变线上定义颜色和相应的位置。
            -> 使用渐变创建QBrush: 用QLinearGradient对象来创建一个QBrush,然后用它在QPainter中进行绘制。
          * API示例:

 void Widget::paintEvent(QPaintEvent * event)
 {
      QPainter painter(this);

      QLinearGradient lineGradient(0, 0, width(), 0);
      lineGradient.setColorAt(0.0, Qt::white);
      lineGradient.setColorAt(1.0, Qt::black);

      QBrush brush(lineGradient);
      painter.setBrush(brush);

      painter.drawRect(rect());
 }


      (2)、径向渐变
          * QRadialGradient是Qt框架中用于创建径向渐变的类。
          * 径向渐变是一种从中心点向外部辐射的颜色渐变,通常在中心点有一种颜色,而向外围渐渐变化为另一种颜色。
          * 径向渐变非常适合用于模拟光源、阴影或创建圆形的立体感。
          * 基本用法:
            -> 创建QRadialGradient对象: 指定渐变的中心点,半径以及焦点(可选)。
            -> 设置颜色停靠点: 在径向渐变中定义颜色和对应的位置。
            -> 使用渐变创建QBrush: 利用QRadialGradient对象创建一个QBrush,然后用它在QPainter中进行绘制。
          * API示例:

void Widget::paintEvent(QPaintEvent * event)
{
     QPainter painter(this);

     QRadialGradient radialGradient(450, 400, 500);
     radialGradient.setColorAt(0.0, Qt::white);
     radialGradient.setColorAt(1.0, Qt::black);
                
     painter.setBrush(QBrush(radialGradient));
     painter.drawRect(300, 300, 300, 200);
}


      (3)、圆锥形渐变
          * QConicalGradient是Qt框架中用于创建圆锥形渐变的类。
          * 圆锥型渐变是一种渐变效果,其中颜色沿着圆锥的轮廓变化,类似于旋转颜色轮。
          * 这种渐变以其中心点为基点,颜色沿圆周分布,可以创建出富有动感的视觉效果。
          * QConicalGradient非常适合用于创建旋转或动态效果的图形,例如加载指示器、进度条或任何需要圆周颜色变化的场景。
          * 基本用法:
            -> 创建QConicalGradient对象: 指定渐变的中心点和起始角度(范围0-360度)。
            -> 设置颜色停靠点: 为渐变添加不同的颜色和对应的位置。
            -> 使用渐变创建QBrush: 使用这个渐变对象来创建一个QBrush,然后应用到QPainter中进行绘制。
          * API示例:

void Widget::paintEvent(QPaintEvent * event)
{
      QPainter painter(this);

      QConicalGradient conicalGradient(400, 300, 0);
      conicalGradient.setColorAt(0.0, Qt::red);
      conicalGradient.setColorAt(0.3, Qt::green);
      conicalGradient.setColorAt(0.6, Qt::blue);
      conicalGradient.setColorAt(0.9, Qt::yellow);
      conicalGradient.setColorAt(1.0, Qt::red);
      painter.setBrush(QBrush(conicalGradient));

      painter.drawRect(200, 200, 400, 200);
}


          * 注意:
            -> QConicalGradient的颜色是沿着圆周分布的,其中0.0和1.0在圆周上是相同的位置。
            -> QConicalGradient起始点(0度)是在三点钟方向。
            -> 为了达到最佳的渲染效果,可以启用QPainter的抗锯齿渲染提示(QPainter::Antialiasing)。
      
 

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

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

相关文章

【云商城】高性能门户网构建

第3章 高性能门户网构建 网站门户就是首页 1.OpenResty 百万并发站点架构 ​ 1).OpenResty 特性介绍 ​ 2).搭建OpenResty ​ 3).Web站点动静分离方案剖析 2.Lua语法学习 ​ 1).Lua基本语法 3.多级缓存架构实战 ​ 1).多级缓存架构分析 用户请求网站,最开始…

上海亚商投顾:沪指探底回升微涨 机器人概念股午后爆发

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天探底回升,沪指盘中跌超1.6%,创业板指一度跌逾3%,午后集体拉升翻红…

计算机毕业设计Python机器学习农作物健康识别系统 人工智能 图像识别 机器学习 大数据毕业设计 算法

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

游戏语音的历史是什么样的?

游戏中,离不开游戏社交。 无社交,不游戏,大家都深知社交在游戏体验中的重要性。 游戏语音的发展史是怎么样的?问了下AI,给我的回答是 早期阶段 1970年代:1970年代出现了第一个语音游戏“尤瓦尔的冒险”&am…

《解锁图像的语言密码:Image Caption 开源神经网络项目全解析》

《解锁图像的语言密码:Image Caption 开源项目全解析》 一、开篇:AI 看图说话时代来临二、走进 Image Caption 开源世界三、核心技术拆解:AI 如何学会看图说话(一)深度学习双雄:CNN 与 RNN(二&a…

毕业设计选题

你是不是正在纠结毕业设计该如何完成?不知道该如何选题?同时又觉得定制太昂贵?你是不是还在为毕业论文不会写而苦恼? 当你看到这儿,就不用再纠结再苦恼了,周哥为你提供了计算机专业各个方向的选题,包括Jav…

linux RT-Preempt spin lock实现

一、spin_lock概述 Spinlock是linux内核中常用的一种互斥锁机制,和mutex不同,当无法持锁进入临界区的时候,当前执行线索不会阻塞,而是不断的自旋等待该锁释放。正因为如此,自旋锁也是可以用在中断上下文的。也正是因为…

Ubuntu 22.04 桥接配置

1. 网卡配置文件备份 sudo cp /etc/netplan/01-network-manager-all.yaml /etc/netplan/01-network-manager-all.yaml.bak 1.1 静态ip配置 1.1.3 解释 network: version: 2 ethernets: # 网卡名称 使用ifconfig查看 ens33: dhcp4: false dhcp6: false …

PHP多功能投票小程序源码

多功能投票小程序:全方位打造专属投票盛宴的得力助手 🎉 🔧 基于先进的ThinkPHP框架与Uniapp技术深度融合,我们匠心独运,精心雕琢出一款功能全面、操作便捷的投票小程序,旨在为您带来前所未有的投票体验。…

[fastadmin] 第三十四篇 FastAdmin 商城模块标签使用详解

FastAdmin 商城模块标签使用详解 一、标签基本语法 1.1 基础语法格式 {shop:goodslist flag"参数值" id"变量名" row"数量"}<!-- 循环内容 --> {/shop:goodslist}1.2 常用参数说明 flag: 商品标记筛选id: 循环变量名row: 显示数量 1.…

二维数组-

定义&#xff1a;二维数组本质上也就是一维数组&#xff0c;只不过每个元素又是一个一维数组 基本语法&#xff1a; 数据类型[][] 数组名称 new 数据类型 [行数][列数] {}初始化数据; 示例&#xff1a; public class Test {public static void main(String[] args) {int[]…

软件测试预备知识④—NTFS权限管理、磁盘配额与文件共享

在软件测试的实际环境搭建与管理过程中&#xff0c;了解和掌握NTFS权限管理、磁盘配额以及文件共享等知识至关重要。这些功能不仅影响系统的安全性和稳定性&#xff0c;还对测试数据的存储、访问以及多用户协作测试有着深远的影响。 一、NTFS权限管理 1.1 NTFS简介 NTFS&am…

自动控制原理初识

文章目录 1.引言2.自动控制原理2.1方框图的案例2.2方框图里面的相关符号2.3闭环控制系统的特点2.4三种基础控制方式2.5对于控制系统的基本要求2.6自动控制原理的体系架构 3.控制系统的数学模型3.1为什么建模3.2建模的方法3.3什么是线性系统3.4线性or非线性系统判断3.5时变or定常…

计算机网络(二)——物理层和数据链路层

一、物理层 1.作用 实现相信计算机节点之间比特流的透明传输&#xff0c;尽可能屏蔽具体传输介质和物理设备的差异。 2.数据传输单位 比特。 3.相关通信概念 ①信源和信宿&#xff1a;即信号的发送方和接收方。 ②数据&#xff1a;即信息的实体&#xff0c;比如图像、视频等&am…

Linux_进程间通信_共享内存

什么是共享内存&#xff1f; 对于两个进程&#xff0c;通过在内存开辟一块空间&#xff08;操作系统开辟的&#xff09;&#xff0c;进程的虚拟地址通过页表映射到对应的共享内存空间中&#xff0c;进而实现通信&#xff1b;物理内存中的这块空间&#xff0c;就叫做共享内存。…

【linux系统】mysql 数据库迁移至新服务器

文章目录 前言一、新服务器停止数据库服务&#x1f6d1;二、旧服务器打包数据库的data目录&#x1f9f3;三、进入新服务器中打包整个数据库的 data 目录&#xff08;备份&#xff09;四、在新服务器中解压旧服务器打包数据库的 data 目录到数据库data 目录中五、修改新数据库 m…

【数据结构:前缀树Trie】

目录 前言前缀树介绍和应用一、前缀树的定义前缀树的问题和思考前缀树的映射思想前缀树三大性质 二.前缀树节点结构三. 前缀树接口介绍和实现四个接口API1. insert(String word)2. search(String word)3. startsWith(String pre)4. delete(String word) API实现1. 查询操作sear…

数据库高安全—角色权限:权限管理权限检查

目录 3.3 权限管理 3.4 权限检查 书接上文数据库高安全—角色权限&#xff1a;角色创建角色管理&#xff0c;从角色创建和角色管理两方面对高斯数据库的角色权限进行了介绍&#xff0c;本篇将从权限管理和权限检查方面继续解读高斯数据库的角色权限。 3.3 权限管理 &#x…

数据集-目标检测系列- 石榴 检测数据集 pomegranate >> DataBall

数据集-目标检测系列- 石榴 检测数据集 pomegranate >> DataBall DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(fre…

搭建一个本地轻量级且好用的学习TypeScript语言的环境

需求说明 虽然 TypeScript 的在线 Playground 很方便 https://www.tslang.com.cn/play/&#xff0c;但毕竟是在浏览器中使用&#xff0c;没有本地的 IDE 那么顺手。所以我想搭建一个本地类似 Playground 的环境&#xff0c;这样在学习 TypeScript 的过程中&#xff0c;可以更方…