当前位置: 首页 > news >正文

界面优化 - 绘图

目录

1. 基本概念

2. 绘制各种形状

2.1 绘制线段

2.2 绘制矩形 

2.3 绘制圆形

2.4 绘制文本

2.5 设置画笔

2.6 设置画刷

3. 绘制图片

3.1 绘制简单图片

3.2 平移图片

3.3 缩放图片

3.4 旋转图片


1. 基本概念

虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就可以应对所有场景.

很多时候我们需要更强的 "自定制" 能力.

Qt 提供了画图相关的 API, 可以允许我们在窗上绘制任意的图形形状, 来完成更复杂的界面设计.

  • 所谓的 "控件" , 本质上也是通过画图的方式画上去的.

  • 画图 API 和 控件 之间的关系, 可以类比成机器指令和高级语言之间的关系.
  • 控件是对画图 API 的进一步封装; 画图 API 是控件的底层实现.

绘图 API 核心类:

说明
QPainter"绘画者" 或者 "画家". 用来绘图的对象, 提供了⼀系列 drawXXX 方法, 可以允许我们绘制各种图形.
QPaintDevice"画板". 描述了 QPainter 把图形画到哪个对象上. 像我们之前用过的 QWidget 也是⼀种 QPaintDevice (QWidget 是 QPaintDevice 的子类) .
QPen"画笔". 描述了 QPainter 画出来的线是什么样的.
QBrush"画刷". 描述了 QPainter 填充一个区域是什么样的.

绘图 API 的使用, 一般不会在 QWidget 的构造函数中使用, 而是要放到 paintEvent 事件中.

🌴关于 paintEvent

paintEvent 会在以下情况下被触发:

  • 控件首次创建.
  • 控件被遮挡, 再解除遮挡.
  • 窗口最小化, 再恢复
  • 控件大小发生变化时.
  • 主动调用 repaint() 或者 update() 方法. (这两个方法都是 QWidget 的方法).
  • ......

因此, 如果把绘图 api 放到构造函数中调用, 那么一旦出现上述的情况, 界面的绘制效果就无法确保符合预期了.

2. 绘制各种形状

2.1 绘制线段

void drawLine(const QPoint &p1, const QPoint &p2);

参数:

  • p1:绘制起点坐标
  • p2:绘制终点坐标

void drawLine ( int x1, int y1, int x2, int y2 );
参数:
  • x1,y1:绘制起点坐标
  • x2,y2:绘制终点坐标

示例:

1、在 "widget.h" 头文件中声明绘图事件;

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();// 声明绘图事件void paintEvent(QPaintEvent *event);private:Ui::Widget *ui;
};

2、在 "widget.cpp" 文件中重写 paintEvent() 方法;

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 1. 画一条线
//    painter.drawLine(50, 50, 500, 50);// 2. 再画一条线painter.drawLine(QPoint(50, 50), QPoint(500, 50));
}

实现效果如下:

2.2 绘制矩形 

void QPainter::drawRect(int x, int y, int width, int height);

参数:

  • x:窗口横坐标;
  • y:窗口纵坐标;
  • width:所绘制矩形的宽度;
  • height:所绘制矩形的高度;

 示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 绘制矩形painter.drawRect(100, 100, 300, 150);
}

实现效果如下:

 

2.3 绘制圆形

 void QPainter::drawEllipse(const QPoint &center, int rx, int ry)

参数:

  • center:中心点坐标
  • rx:横坐标
  • ry:纵坐标

  示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 绘制圆painter.drawEllipse(QPoint(300, 300), 100, 100);
}

 实现效果如下:

2.4 绘制文本

        QPainter类 中不仅提供了绘制图形的功能,还可以使用 QPainter::drawText() 函数来绘制文字也可以使用 QPainter::setFont() 设置字体等信息。

示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 设置字体QFont font("华文行楷", 25);painter.setFont(font);// 设置画笔颜色painter.setPen(Qt::blue);// 画文字painter.drawText(300, 250, "草长莺飞");
}

 实现效果如下:

2.5 设置画笔

        QPainter 在绘制时,是有一个默认的画笔的。在使用时也可以自定义画笔。在 Qt 中,QPen类中定义了 QPainter 应该如何绘制形状、线条和轮廓。同时通过 QPen类 可以设置画笔的线宽、颜色、样式、画刷等。

        画笔的颜色可以在实例化画笔对象时进行设置,画笔的宽度是通过 setWidth() 方法进行设置,画笔的风格是通过setStyle()方法进行设置,画笔的颜色主要是通过 QColor 类设置,设置画刷主要是通过 setBrush() 方法。

  • 设置画笔颜色:QPen::QPen(const QColor &color)
  • 设置画笔宽度:void QPen::setWidth(int width)
  • 设置画笔风格:void QPen::setStyle(Qt::PenStyle style)

画笔的风格有:


示例:画笔的使用

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 设置画笔QPen pen(QColor(0, 255, 255));// 设置画笔宽度pen.setWidth(5);// 设置画笔风格pen.setStyle(Qt::DashLine);// 让画家使用画笔painter.setPen(pen);// 绘制圆painter.drawEllipse(QPoint(300, 300), 100, 100);
}

实现效果如下:

2.6 设置画刷

        在 Qt 中,画刷是使用 QBrush类 来描述,画刷大多用于填充。QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。

        画刷的格式中定义了填充的样式,使用 Qt::BrushStyle 枚举,默认值是 Qt::NoBrush,也就是不进行任何填充。可以通过 Qt 助手查找画刷的格式。如下图示:

设置画刷主要通过 void QPen::setBrush(const QBrush &brush) 方法,其参数为画刷的格式


示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;// 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备QPainter painter(this);// 设置画刷,给封闭图形填充颜色QBrush brush(QColor(255, 0, 255));// 设置画刷风格brush.setStyle(Qt::DiagCrossPattern);// 让画家使用画刷painter.setBrush(brush);// 绘制圆painter.drawEllipse(QPoint(300, 300), 100, 100);
}

 实现效果如下:

3. 绘制图片

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

3.1 绘制简单图片

1. 新建 Qt 项目,基类选择 QWidget,项目名称为 QPainter。在 "widget.h" 头文件中声明绘画事件;如下图示:

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();// 声明绘画事件void paintEvent(QPaintEvent *event);private:Ui::Widget *ui;
};

2. 创建 resource.qrc,并导入图片

3. 在 "widget.cpp" 文件中实现画图片功能;

void Widget::paintEvent(QPaintEvent *event)
{// 实例化画家对象(void)event;QPainter painter(this);// 画图片painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

3.2 平移图片

        平移图片实际是通过改变坐标来实现。QPainter类中提供了 translate()函数 来实现坐标原点的改变。

示例:

void Widget::paintEvent(QPaintEvent *event)
{// 实例化画家对象(void)event;QPainter painter(this);// 平移图片painter.translate(100, 100);// 画图片painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

3.3 缩放图片

在 Qt 中,图片的放大和缩小可以使用 QPainter类 中的 drawPixmap()函数 来实现。

示例:

void Widget::paintEvent(QPaintEvent *event)
{// 实例化画家对象(void)event;QPainter painter(this);QPixmap pixmap(":/fengche.jpg");// 缩放图片// 以(100,100)点开始画图,图片尺寸变为:400 * 300painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

3.4 旋转图片

图片的旋转使用的是 QPainter类 中的 rotate()函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用 translate()函数 完成。

示例:

void Widget::paintEvent(QPaintEvent *event)
{// 实例化画家对象(void)event;QPainter painter(this);QPixmap pixmap(":/fengche.jpg");// 顺时针旋转 180 度painter.rotate(180);painter.translate(-800, -600);painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

相关文章:

界面优化 - 绘图

目录 1. 基本概念 2. 绘制各种形状 2.1 绘制线段 2.2 绘制矩形 2.3 绘制圆形 2.4 绘制文本 2.5 设置画笔 2.6 设置画刷 3. 绘制图片 3.1 绘制简单图片 3.2 平移图片 3.3 缩放图片 3.4 旋转图片 1. 基本概念 虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就…...

死锁问题分析和解决——资源回收时

1.描述问题 在完成线程池核心功能功能时,没有遇到太大的问题(Any,Result,Semfore的设计),在做线程池资源回收时,遇到了死锁的问题 1、在ThreadPool的资源回收,等待线程池所有线程退出时&#xff…...

【Java】效率工具模板的使用

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1 乱码问题4.2 快捷键模板4.3 文件模板 一、前言 提高效率 二、学习内容&am…...

c++指南 -指针和引用

指针和引用 指针的基本概念 指针是存储另一个变量的内存地址的变量。指针变量的声明包括指针类型和星号 (*)。 int* ptr; // ptr 是一个指向 int 类型的指针指针操作 初始化:将指针设置为变量的地址。 int var 10; int* ptr &var; // ptr 现在存储 var 的…...

[CISCN 2023 华北]ez_date

[CISCN 2023 华北]ez_date 点开之后是一串php代码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); class date{public $a;public $b;public $file;public function __wakeup(){if(is_array($this->a)||is_array($this->b)){die(no array);}if( (…...

前端不同项目使用不同的node版本(Volta管理切换)

前端不同项目使用不同的node版本(Volta管理切换) 使用volta自动切换前端项目的node版本&#xff0c; 每个不同的前端项目&#xff0c;可以使用不同的node版本。Volta这个工具&#xff0c;它允许用户方便地安装、切换和管理不同版本的Node.js&#xff0c;避免了为每个项目手动配…...

Ropdump:针对二进制可执行文件的安全检测工具

关于Ropdump Ropdump是一款针对二进制可执行文件的安全检测工具&#xff0c;该工具基于纯Python开发&#xff0c;是一个命令行工具&#xff0c;旨在帮助广大研究人员检测和分析二进制可执行文件中潜在的ROP小工具、缓冲区溢出漏洞和内存泄漏等安全问题。 功能介绍 1、识别二进…...

Quartz - 定时任务框架集成

参考了若依框架&#xff0c;将quartz定时任务框架集成到自己的项目当中。 目录 一、Quartz概述二、库表创建1.Quartz关键表&#xff08;11张&#xff09;表SQL 2.自定义业务表&#xff08;2张&#xff09;表SQL 三、代码示例1.依赖引入2.类文件1&#xff09;定时任务配置类2&am…...

GoModule

GOPATH 最早的就是GOPATH构建模式&#xff0c; go get下载的包都在path中的src目录下 src目录是源代码存放目录。 package mainimport ("net/http""github.com/gorilla/mux" )func main() {r : mux.NewRouter()r.HandleFunc("/hello", func(w h…...

SQL - 数据库管理

保障数据库安全的用户账户和权限问题&#xff0c;当在工作环境中使用MySQL的时候&#xff0c;我们需要创建其他用户账户&#xff0c;并赋予它们特定权限。创建一个用户 create user wolf127.0.0.1 identified by 1234; create user wolf127.0.0.1 identified by 1234;-- 无 …...

密码学之AES算法

文章目录 1. AES简介1.1 AES算法的历史背景1.2 AES算法的应用领域 2. AES加解密流程图2. AES算法原理2.1 AES加密过程2.2 AES解密过程 1. AES简介 1.1 AES算法的历史背景 AES算法&#xff0c;全称为Advanced Encryption Standard&#xff08;高级加密标准&#xff09;&#x…...

GitHub每日最火火火项目(8.20)

项目名称&#xff1a;goauthentik / authentik 项目介绍&#xff1a;authentik 是一款提供认证功能的工具&#xff0c;它就像是一个强大的粘合剂&#xff0c;能够满足您在认证方面的各种需求。无论是在安全验证、用户身份管理还是访问控制等方面&#xff0c;它都能发挥重要作用…...

(五)Flink Sink 数据输出

经过上面的 Transformation 操作之后,最终形成用户所需要的结果数据集。通常情况下,用户希望将结果数据输出到外部存储介质或者传输到下游的消息中间件中,在 Flink 中,将 DataStream 数据输出到外部系统的过程被定义为 Sink 操作。 目录 (一)基本数据输出 (二)第三方…...

Spring 注入、注解及相关概念补充

一、Spring DI 的理解 DI ( Dependency Inject&#xff0c;中文释义&#xff1a;依赖注入)是对 IOC 概念不同角度的描述&#xff0c;是指应用程序在运行时&#xff0c;每一个 bean 对象都依赖 IOC 容器注入到当前 bean 对象所需要的另一个 bean 对象。&#xff08;例如&#xf…...

【Linux多线程】线程安全的单例模式

文章目录 1. 单例模式 与 设计模式1.1 单例模式1.2 设计模式1.3 饿汉实现模式 与 懒汉实现模式1.4 饿汉模式① 饿汉模式的特点② 饿汉式单例模式的实现③ 饿汉式单例模式的优缺点④ 适用场景 1.5 懒汉模式① 懒汉式单例模式的特点② 懒汉式单例模式的实现③ 懒汉式单例模式的优…...

基于jqury和canvas画板技术五子棋游戏设计与实现(论文+源码)_kaic

摘 要 网络五子棋游戏如今面临着一些新的挑战和机遇。一方面&#xff0c;网络游戏需要考虑到网络延迟和带宽等因素&#xff0c;保证游戏的实时性和稳定性。另一方面&#xff0c;网络游戏需要考虑到游戏的可玩性和趣味性&#xff0c;以吸引更多的玩家参与。本文基于HTML5和Canv…...

指针 (四)

一 . 指针的使用和传值调用 &#xff08;1&#xff09;strlen 的模拟实现 库函数 strlen 的功能是求字符串长度&#xff0c;统计的是字符串中 \0 之前的字符个数&#xff0c;函数原格式如下&#xff1a; 我们的参数 str 接收到一个字符串的起始地址&#xff0c;然后开始统计…...

便利店(超市)管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…...

Excel中的“块”操作

在Excel中&#xff0c;有offset、index、indirect三个对“区域”操作的函数&#xff0c;是较高版本Excel中“块”操作的利器。 (笔记模板由python脚本于2024年08月20日 19:25:21创建&#xff0c;本篇笔记适合喜欢用Excel处理数据的coder翻阅) 【学习的细节是欢悦的历程】 Pytho…...

yolo V8训练 长条状目标

1、说明 目标数据集合中有很多长条状图片&#xff0c;如果直接Resize 会严重拉伸&#xff0c;因此采用把长条图像裁剪成2段&#xff0c;然后将裁剪后的2段图片拼接在一起。 2、代码 2.1 C 代码 &#xff08;部署&#xff0c;模型推理时C &#xff09; #include <stdio.h…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...