【Qt】探索Qt绘图世界:自定义控件与视觉效果的全面指南

文章目录

  • 前言:
  • 1. 绘图基本概念
  • 2. 绘制各种形状
  • 3. 绘制文字(显示文字)、设置画笔
  • 4. 画刷
  • 5. 绘制图片
  • 6. 特殊的绘图设备
  • 总结:

前言:

在软件开发中,图形用户界面(GUI)的设计是至关重要的。Qt,作为一个跨平台的应用程序框架,提供了一套强大的工具和控件来帮助开发者创建美观且功能丰富的用户界面。然而,当现有的控件无法满足特定需求时,开发者就需要利用Qt提供的绘图API来自定义控件和效果。本文将详细介绍Qt中的绘图基本概念,包括绘制形状、文字、设置画笔和画刷、以及使用特殊的绘图设备等,旨在帮助开发者更好地理解和运用Qt的绘图功能。

1. 绘图基本概念

绘图:画画
前面学习 Qt 主要是学习 Qt 的各种控件 -> 本质上都是画出来的
Qt 的各种控件:都是一些常用的的东西,Qt 已经提前画好了,拿过来拿过来就能使用。
实际开发中,很有可能现有的控件无法满足需求,就需要自己 DIY 一些控件/效果。
Qt 提供的 绘图API就是为了解决上述问题的。
实际开发中大部分情况不需要使用绘图API

QPainter: 提供一系列的绘图方法,实现绘图的动作。
QPaintDevice: “画板”,你要画的内容是往啥东西上画,QWidger 就是 QPaintDevice 的子类。
QPen: “画笔” ,描述了 QPainter 画处来的线是什么样的。
QBrush: “画刷” 描述了 QPainter 填充一个区域是什么样的。

一个关键的注意事项:
画图相关的操作,一般不会放到 QWidget 的构造函数中调用执行,而是Qt提供了一个paintEven事件处理函数,在这里进行调用。

painEvent: 和它对应的,会有一个 QPaintEvent 事件

  1. 控件首次创建的时候;比如往 QWidget 上画画,QWidget 创建之前,画的东西当然不生效。首次创建 QWidget 就能显示出画的东西来。
  2. 控件被遮挡,再解除遮挡;这个时机进行绘制也是很重要的,否则绘制的内容就会在被遮挡之后就没了。
  3. 窗口最小化,再还原、
  4. 控件大小发生改变的时候
  5. 主动在代码中调用 repaint 或者 update 触发事件。(都是 QWidget提供的成员函数)

2. 绘制各种形状

QPainter painter(this);

这是定义在栈上的变量,不需要考虑释放的问题,此处指定的 this,不是父对象,而是指定绘制的设备(往啥东西上画)

void paintEvent(QPaintEvent *event); // 重写 paintEvent函数
void Widget::paintEvent(QPaintEvent *event)
{(void) event;// 绘图工作就会放到这里来执行QPainter painter(this);// 画一个线段painter.drawLine(20, 20, 200, 20);painter.drawLine(QPoint(20, 100), QPoint(200, 100));// 画一个矩形painter.drawRect(100, 100, 300, 200);// 画一个圆形painter.drawEllipse(200, 200, 100, 100); // 100,100 为外界矩形的宽度和高度
}

在这里插入图片描述

3. 绘制文字(显示文字)、设置画笔

painter.drawText(0, 100, "hello");

注意理解这里的坐标位置
此处的 0 横坐标,表示的是文字最左侧的位置。 此处的 100 纵坐标,表示的是文字的
“基线位置(baseline)”(四线格第三根线)

通过 Qpen 设置绘制的形状的颜色、粗细、样式
在这里插入图片描述

void Widget::paintEvent(QPaintEvent *event)
{(void) event;// 绘图工作就会放到这里来执行QPainter painter(this);QFont font("微软雅黑", 24);painter.setFont(font);QPen pen;// 设置为成红色的pen.setColor(QColor(255, 0, 0));// 设置线条的粗细pen.setWidth(5);// 设置线条的风格pen.setStyle(Qt::DashLine);// 让 painter 对象应用 pen 对象painter.setPen(pen);//    // 画一个线段
//    painter.drawLine(20, 20, 200, 20);
//    painter.drawLine(QPoint(20, 100), QPoint(200, 100));//    // 画一个矩形
//    painter.drawRect(100, 100, 300, 200);// 画一个圆形painter.drawEllipse(200, 200, 100, 100); // 100,100 为外界矩形的宽度和高度// 绘制文本painter.drawText(0, 100, "hello");
}

在这里插入图片描述

4. 画刷

QBrush 画刷:内部填充的:颜色、风格
在这里插入图片描述

QBrush brush;
brush.setColor(QColor(0, 255, 0));
painter.setBrush(brush);
// brush.setStyle(Qt::SolidPattern); // 实心填充
brush.setStyle(Qt::CrossPattern);
painter.setBrush(brush);

在这里插入图片描述

5. 绘制图片

Qt 提供了四个类来处理图像数据:QImageQPixmapQBitmapQPicture,它们都是常用的绘图设备。其中QImage主要用来进行 I/O 处理,它对 I/O 处理操作进行了优化,而且可以用来直接访问和操作像素;QPixmap 主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;QBitmapQPixmap 的子类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;QPicture 用来记录并重演 QPainter 命令。
QPixmap

void Widget::paintEvent(QPaintEvent *event)
{(void)event;QPainter painter(this);QPixmap pixmap(":/picture.jpg");//    // 基础绘制
//    painter.drawPixmap(50, 50, pixmap);// 图片缩放painter.drawPixmap(100, 100, 400, 300, pixmap);
}

在这里插入图片描述
旋转:

painter.rotate(180); // 绕着(0, 0) 坐标写原点进行旋转

为了能够让图片显示出来,可以把坐标系原点(Painter 的起点)平移一下,比如可以平移到窗口右下角。

旋转图片后 ,坐标就反过来了,此时往右移动,就是 x 要减小,往下移动,y 就要变大。

// 图片旋转,本质上是把 QPainter 对象进行了旋转,绘制的内容也就产生了旋转
painter.rotate(180); // 绕着(0, 0) 坐标写原点进行旋转
painter.translate(-800, -600); // 平移 
painter.drawPixmap(100, 100, 400, 300, pixmap);

在这里插入图片描述

6. 特殊的绘图设备

QPixmap:
在这里插入图片描述
QImage: 还允许对图片进行像素级编辑
QPixmap: 用于显示器上显示
QBitmap:特殊的Pixmap
QPicture: 对QPainter 的一系列操作步骤给记录下来

总结:

本文从Qt的绘图基本概念出发,逐步深入到形状的绘制、文字的显示、画笔和画刷的设置,以及图片的绘制等多个方面。我们了解到,虽然Qt提供了丰富的控件库,但在某些情况下,我们仍需通过自定义绘图来实现特定的视觉效果。通过使用QPainterQPaintDeviceQPenQBrush等类,我们可以在QWidget等画板上实现各种复杂的绘图操作。此外,文章还介绍了如何使用QImageQPixmapQBitmapQPicture等类来处理图像数据,以及如何通过旋转和缩放等变换来增强图像的显示效果。通过本文的学习,开发者应该能够更加自如地运用Qt的绘图API,创造出更加个性化和专业的用户界面。

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

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

相关文章

Unity中帧动画素材的切割设置

有几个问题,美术在给我们帧动画的时候,一般都是给一个比较大的图,然后进行切割成多个sprite,导入到animation中 一般来说,进行那个autoSlide,自动切割就可以了 这个自动切割的图片会沿着有像素的最小包围…

【1】AI介绍

迎接 AGI 时代 AGI(Artificial General Intelligence),人工通用智能,AGI是一种可以执行复杂任务的人工智能,能够完全模仿人类智能的行为。应用领域涉及医疗、交通、智能家居等多个与人类活动密切相关的领域。 AGI 多久会到来? 乐观预测:明年(未来已来)主流预测:3-5…

RHEL7.9修改分区

系统RHEL7.9 他因为安装软件,需要修改分区 进入超级用户root,输入lsblk 查看分区,可见465.8G系统盘sda下有三个物理卷,其中sda3下/home有410.6G,需要这部分拆分出200G软件和100G的数据库分区 备份/home 目录下文件 c…

GDPU unity游戏开发 动画状态机

每一个动画状态都演绎着你的奔赴。 动画混合 1) 前往 Mixamo选择适合的角色模型和idle/walking/backward动画并下载。确保下载时选择FBX for Unity格式。 2) 新建Unity项目,导入下载的模型。 3) 在导入模型的Inspector窗口中,选择Materials选项卡&a…

分治策略的实现

目录 前言 分治策略的应用 最大子数组问题 矩阵乘法问题 求解递归式的三种方法 代入法求递归式 用递归树求递归式 主方法求递归式 前言 分治三个步骤: 分解:分解原问题为子问题,这些子问题为原问题的较小规模的问题。 解决&#xf…

浅谈SpringBoot日志文件

文章目录 一、日志的作用二、如何在SpringBoot中使用日志2.1、在程序中得到日志对象。2.2、通过日志对象中提供的内置方法操打印日志信息2.2.1 日志级别2.2.1.1、日志级别有什么作用??2.2.1.2、日志级别的分类2.2.1.2、在配置文件中设置日志级别[!] 三、…

Linux线程:线程分离

目录 一、什么是线程分离 1.1pthread_detach 1.2pthread线程库存在的意义 1.3__thread线程的局部存储 1.4系统调用clone 一、什么是线程分离 1.1pthread_detach 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_joi…

非对称密钥:应用场景

public class EncryptionAndSignatureExample { public static void main(String[] args) throws Exception {// 生成公私钥对KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(1024);KeyPair keyPair keyPai…

路由策略实验2

对R7,重发布直连路由 对R2,做双向 对R3同样 先不改优先级 查看,知道所有给R3的路由为151,全部为OSPF。 知道了是错误的,先把3,4之间的线路断掉 接着对R3,让优先级全部回到100(displa…

node-sass和sass-loader安装Error经验

一、问题 当前笔记本环境版本:node-v16.15.1;npm-8.11.0,在面对五年前vue项目的依赖sass-loader8.0.2,node-sass4.14.1的情况下,怎么参考大神们的安装教程,始终存在Error,经过坚持不懈的努力&a…

微软云计算之云计算平台、云操作系统Windows Azure

微软云计算平台 微软云计算平台微软的云计算技术Windows Azure组成 微软云操作系统Windows AzureWindows Azure概述Windows Azure计算服务Windows Azure存储服务全局命名空间体系架构存储域的层次结构双复制引擎文件流层分区层 Windows Azure ConnectWindows Azure CDNFabric控…

十_信号11 - 函数sigsetjmp() 和 siglongjmp()

也就是说,正常情况下,当捕捉到一个信号,并调用该信号的信号处理程序时,被捕捉的信号会被加入到当前进程的信号屏蔽字中,以防止在本次信号处理程序还没有完成的时候,再次触发该信号, 发生重入。 …

LLaMA-Factory实战推理

LLaMA-Factory官网:https://github.com/hiyouga/LLaMA-Factory 安装环境 git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory/ conda create -n py310 python3.10 conda activate py310按照llama-factory要求的标准格式组织数据集&#xff…

网络原理——http/https ---http(2)

http(接上一篇文章) 认识请求报头"header" header里面的键值对,都是标准规定的内容,很多,我们主要是认识一些关键的 host 表示对应的服务器主机的IP / 域名 实际上,这两个通常来说是一样的 但是有些时候不一样 当我们通过代码构造http请求,url里面写的以Ip地址的…

6月2(信息差)

🌍特斯拉:Model3高性能版预计6月中旬开启首批交付 🎄微软对开源字体 Cascadia Code 进行重大更新 ✨天猫618加码引爆消费热潮 截至晚9点185个品牌成交破亿 1.瑞士清洁科技公司Librec开发废旧锂离子电池回收技术,可回收电池90%的…

贴片和直插型IRM红外遥控接收头引脚定义和规格参数及使用注意事项

红外遥控接收头使用注意事项 引脚定义存在不同 红外遥控接收头大量使用在家用电器的遥控中,属于价廉物美的一种光电接收器件,批量价格约0.3元左右。 多数遥控接收头的引脚定义是OUT,GND,VCC,另有引脚定义不同为OUT,VCC,GND,记住…

Django 创建项目及应用

1,安装 Django pip install Django3.1.5 2,创建 Django项目 django-admin startproject myshop 3,创建 Django应用 python manage.py startapp app1 4,启动 Django项目 python .\manage.py runserver 到这里项目及应用创建…

空间转录组基础数据解读+学习方法

详情请参考这个视频:空间转录组(spatial transcriptome)数据分析基础教程_哔哩哔哩_bilibili 1.首先是filtered_feature_bc_matrix文件 两个里面的内容本质一样,都是空间转录组 表达矩阵的信息 2.具体的所有东西可以在10x的网站…

React(五)UseEffect、UseRef

(一)useEffect useEffect – React 中文文档 useEffect hook用于模拟以前的class组件的生命周期,但比原本的生命周期有着更强大的功能 1.类组件的生命周期 在类组件编程时,网络请求,订阅等操作都是在生命周期中完成 import React, { Co…

图书推荐:ChatGPT专业知识信息课程

《ChatGPT专业知识信息课程》(ChatGPT-Expertise Informative Course) 是一本由Dwayne Anderson撰写的电子书,提供了关于ChatGPT的丰富知识。该书涵盖了与ChatGPT相关的各种主题,如其与OpenAI的关系、ChatGPT与GPT-3之间的混淆、C…