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

2024-06-02 20:04

本文主要是介绍【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,创造出更加个性化和专业的用户界面。

这篇关于【Qt】探索Qt绘图世界:自定义控件与视觉效果的全面指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1024953

相关文章

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

揭秘世界上那些同时横跨两大洲的国家

我们在《世界人口过亿的一级行政区分布》盘点全球是那些人口过亿的一级行政区。 现在我们介绍五个横跨两州的国家,并整理七大洲和这些国家的KML矢量数据分析分享给大家,如果你需要这些数据,请在文末查看领取方式。 世界上横跨两大洲的国家 地球被分为七个大洲分别是亚洲、欧洲、北美洲、南美洲、非洲、大洋洲和南极洲。 七大洲示意图 其中,南极洲是无人居住的大陆,而其他六个大洲则孕育了众多国家和

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s