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

QT之头像剪裁效果实现

文章目录

  • 源码地址,环境:QT5.15,MinGW32位
  • 效果演示
  • 导入图片
  • 设置剪裁区域
  • 创建剪裁小窗口
  • 重写剪裁小窗口的鼠标事件
    • mousePressEvent
    • mouseMoveEvent
    • mouseReleaseEvent
  • 小窗口移动触发父窗口的重绘事件
  • 剪裁效果实现

源码地址,环境:QT5.15,MinGW32位

效果演示

在这里插入图片描述
在这里插入图片描述

导入图片

    QPixmap m_srcPix;QPixmap m_scaledPix;//从文件导入图片m_srcPix.load("D:\\Jolly\\A_0voice_chat\\chapter_explanation\\PictureEdit_demo\\PictureEdit\\images\\1.png");//把导入的图片截取到窗口大小m_scaledPix = m_srcPix.scaled(ui->label->width(), ui->label->height());//在窗口显示图片ui->label->setPixmap(m_scaledPix);

设置剪裁区域

    //裁剪头像活动窗口//设置透明this->setWindowFlags(Qt::FramelessWindowHint);//设置矩形区域,整个窗口this->setGeometry(0, 0, parentWidget()->width(), parentWidget()->height());CutDialog *m_cutDialog;//头像剪切窗口m_cutDialog = new CutDialog(this);m_cutDialog->show();

创建剪裁小窗口

CutDialog::CutDialog(QWidget *parent) :QWidget(parent)
{setGeometry(0,0, 150, 150);m_mouseDown = false;
}

重写剪裁小窗口的鼠标事件

mousePressEvent

void CutDialog::mousePressEvent(QMouseEvent *event)
{//获取鼠标按下时的位置m_startPoint = event->pos();//判断按下的是否是鼠标左键m_mouseDown = event->button() == Qt::LeftButton;
}

mouseMoveEvent

要是没有启用鼠标追踪,mouseMoveEvent 只有在鼠标按键被按下并且鼠标移动时才会触发,而且是在mousePressEvent触发之后。
当启用鼠标追踪后,不管鼠标按键是否被按下,只要鼠标移动,mouseMoveEvent就会触发

void CutDialog::mouseMoveEvent(QMouseEvent *event)
{//获取鼠标移动以后的位置QPoint dragPoint = event->pos();if (m_mouseDown) {//pos保存小部件在其父部件中的位置QPoint p = QPoint(//pos() 是对话框在父窗口中的左上角坐标//dragPoint - m_startPoint 计算鼠标移动的偏移量//原理: 拖动点相对于对话框的位置保持不变(如从(10,10)点开始拖动,移动后仍抓住该点)pos().x()+dragPoint.x() - m_startPoint.x(), // 水平方向pos().y()+dragPoint.y()-m_startPoint.y()    // 垂直方向);QPoint dragEndge = p;dragEndge.setX(p.x() + rect().width());   // 对话框右下角X坐标dragEndge.setY(p.y() + rect().height());  // 对话框右下角Y坐标//左上角约束,保证小窗口左上角在父窗口范围内p.setX(p.x() < 0 ? 0 : p.x());p.setY(p.y() < 0 ? 0 : p.y());//右下角约束// 确保右下角X ≤ 父窗口宽度p.setX(dragEndge.x() > parentWidget()->width()? parentWidget()->width() - rect().width(): p.x());// 确保右下角Y ≤ 父窗口高度p.setY(dragEndge.y() > parentWidget()->height()? parentWidget()->height() - rect().height(): p.y());//QWidget::move() 对窗口部件的位置进行设置move(p);
/*
move函数原型
void move(int x, int y);
void move(const QPoint &pos);*/}}

mouseReleaseEvent

释放鼠标时将m_mouseDown 设置为false,避免鼠标右键或其他案件误触发mouseMoveEvent

void CutDialog::mouseReleaseEvent(QMouseEvent *event)
{m_mouseDown = false;
}

小窗口移动触发父窗口的重绘事件

paintEvent调用时机:

​​首次显示窗口时​​
当 PhotoShotDialog 首次显示(例如通过 show() 或 exec())时,系统会自动触发 paintEvent 进行初始绘制。

​​窗口需要重绘时​​
窗口被其他窗口遮挡后重新暴露出来
窗口内容发生变化(如子窗口移动、尺寸变化)
调用 update() 或 repaint() 方法强制重绘

​​子窗口移动时(关键)​​
当用户拖动 CutDialog时:
CutDialog::mouseMoveEvent() 中调用了 move§ 移动裁剪框
移动操作会​​自动触发父窗口(PhotoShotDialog)的重绘​​,因为:
子窗口位置变化导致父窗口的可见区域需要更新
系统自动发送重绘事件到父窗口

void PhotoShotDialog::paintEvent(QPaintEvent *event)
{QPainterPath painterPath;QPainterPath p;p.addRect(x(),y(),this->rect().width(), this->rect().height()); //裁剪头像活动窗口 (蓝色矩形)//QWidget::geometry()返回一个 QRect 对象。这个对象包含了窗口部件的位置和大小信息painterPath.addRect(m_cutDialog->geometry()); //头像剪切窗口 (紫色矩形)QPainterPath drawPath = p.subtracted(painterPath); //subtracted 获取除了painterPath区域以外的窗口QPainter painter(this);painter.setOpacity(0.6); //设置Qt控件透明度 0表示全透明,1表示不透明painter.fillPath(drawPath, QBrush(Qt::black));
}

剪裁效果实现

void PictureEdit::on_pushButton_clicked()
{//直接复制小窗口的图像内容QPixmap pix = m_scaledPix.copy(m_psDialog->getCutGeometry());//将截图内容重命名,并保存到指定目录pix.save("D:\\work\\workspace\\qtstudyspace\\PictureEdit\\images\\cut.png", "png");
}

相关文章:

QT之头像剪裁效果实现

文章目录 源码地址&#xff0c;环境&#xff1a;QT5.15&#xff0c;MinGW32位效果演示导入图片设置剪裁区域创建剪裁小窗口重写剪裁小窗口的鼠标事件mousePressEventmouseMoveEventmouseReleaseEvent 小窗口移动触发父窗口的重绘事件剪裁效果实现 源码地址&#xff0c;环境&…...

apptrace 视角下移动端深度链接技术与优势​

官网链接&#xff1a;AppTrace - 专业的移动应用推广追踪平台 App 拉起&#xff0c;本质上是移动端深度链接技术的具象化呈现。在这一领域&#xff0c;apptrace 凭借前沿技术与创新理念&#xff0c;实现从 H5 网页到 App 的无缝跳转&#xff0c;精准定位 App 内指定页面&#…...

微前端之micro-app数据通信

在这之前如果还没接触过微前端,可以找一些视频、资料先去了解一下,就不在这里赘述了。 现在常见的微前端框架包括: single-spa micro-app qiankun EMP 无界 目前了解到的基本上是这些哈,大家感兴趣可以自行去了解一下,看下它们之间的区别。 因为我目前使用的是mic…...

【GPT入门】第40课 vllm与ollama特性对比,与模型部署

【GPT入门】第40课 vllm与ollama特性对比&#xff0c;与模型部署 1.两种部署1.1 vllm与ollama特性对比2. vllm部署2.1 服务器准备2.1 下载模型2.2 提供模型服务 1.两种部署 1.1 vllm与ollama特性对比 2. vllm部署 2.1 服务器准备 在autodl 等大模型服务器提供商&#xff0c;…...

unity开发棋牌游戏

使用unity开发的棋牌游戏&#xff0c;目前包含麻将、斗地主、比鸡、牛牛四种玩法游戏。 相关技术 客户端&#xff1a;unity 热更新&#xff1a;xlua 服务器&#xff1a;c Web服务器&#xff1a;ruoyi 游戏视频 unity开发棋牌游戏 游戏截图...

Nat Commun项目文章 ▏小麦CUTTag助力解析转录因子TaTCP6调控小麦氮磷高效利用机制

今年2月份发表在《Nature Communications》&#xff08;IF14.4&#xff09;的“TaTCP6 is required for efficientand balanced utilization of nitrate and phosphorus in wheat”揭示了TaTCP6在小麦氮磷利用中的关键调控作用&#xff0c;为优化肥料利用和提高作物产量提供了理…...

Qt OpenGL 相机实现

在Qt中使用OpenGL实现相机功能主要涉及视图矩阵(view matrix)的操作&#xff0c;包括相机位置、观察方向和上向量等概念。下面我将介绍如何在Qt中实现一个基本的3D相机。 基本概念 OpenGL相机本质上是通过视图矩阵(view matrix)来实现的&#xff0c;它定义了从世界空间到观察…...

云原生时代 Kafka 深度实践:03进阶特性与最佳实践

3.1 数据可靠性与一致性 Producer 端可靠性策略 Kafka 通过acks参数控制消息确认机制&#xff0c;不同设置适用于不同场景&#xff1a; acks0&#xff1a;Producer 发送消息后不等待 Broker 确认&#xff0c;立即返回。这种模式吞吐量最高&#xff0c;但可能丢失消息&#x…...

基于关联表字段映射的批量数据更新 SQL 实现方案(AIGC)

UPDATE po_upfiles u JOIN po_micro m ON u.from_id = m.ent_id_old SET u.from_id = m.ent_id; 我的提问 批量更新po_upfiles数据中from_id=ent_id_old的数据中from_id为ent_id,语句怎么写“问题重新按照适合AI的逻辑进行提问,如何修改 精确版...

Hadoop复习(二)

部署Hadoop 考试不考部署&#xff0c;就复习选择和大题 问题 1 单项选择 2 / 2 分 下面哪个是MapReduce的核心配置文件 core-site.xml hdfs-site.xml yarn-site.xml mapred-site.xml 问题 2 单项选择 2 / 2 分 下面哪个是HDFS的核心配置文件 core-site.xml hdf…...

C 语言开发中常见的开发环境

目录 1.Dev-C 2.Visual Studio Code 3.虚拟机 Linux 环境 4.嵌入式 MCU 专用开发环境 1.Dev-C 使用集成的 C/C 开发环境&#xff08;适合基础学习&#xff09;,下载链接Dev-C下载 - 官方正版 - 极客应用 2.Visual Studio Code 结合 C/C 扩展 GCC/MinGW 编译器&#xff0c…...

vscode命令行debug

vscode命令行debug 一般命令行debug会在远程连服务器的时候用上&#xff0c;命令行debug的本质是在执行时暴露一个监听端口&#xff0c;通过进入这个端口&#xff0c;像本地调试一样进行。 这里提供两种方式&#xff1a; 直接在命令行中添加debugpy&#xff0c;适用于python…...

Matlab作图之 subplot

1. subplot(m, n, p) 将当前图形划分为m*n的网格&#xff0c;在 p 指定的位置创建坐标轴 matlab 按照行号对子图的位置进行编号 第一个子图是第一行第一列&#xff0c;第二个子图是第二行第二列......... 如果指定 p 位置存在坐标轴&#xff0c; 此命令会将已存在的坐标轴设…...

Springboot 项目一启动就获取HttpSession

在 Spring Boot 项目中&#xff0c;HttpSession 是有状态的&#xff0c;通常只有在用户发起 HTTP 请求并建立会话后才会创建。因此&#xff0c;在项目启动时&#xff08;即应用刚启动还未处理任何请求&#xff09;是无法获取到 HttpSession 的。 方法一&#xff1a;使用 HttpS…...

PostgreSQL的扩展 insert_username

PostgreSQL的扩展 insert_username insert_username 是 PostgreSQL 的一个实用扩展&#xff0c;用于自动记录数据行的创建者和最后修改者信息。这个扩展特别适合需要审计跟踪的应用场景。 一 扩展安装与启用 1.1 安装扩展 -- 使用超级用户安装 CREATE EXTENSION insert_use…...

【机器学习基础】机器学习入门核心算法:层次聚类算法(AGNES算法和 DIANA算法)

机器学习入门核心算法&#xff1a;层次聚类算法&#xff08;AGNES算法和 DIANA算法&#xff09; 一、算法逻辑二、算法原理与数学推导1. 距离度量2. 簇间距离计算&#xff08;连接标准&#xff09;3. 算法伪代码&#xff08;凝聚式&#xff09; 三、模型评估1. 内部评估指标2. …...

Google Play的最新安全变更可能会让一些高级用户无法使用App

喜欢Root或刷机的Android用户要注意了&#xff0c;Google最近全面启用了新版Play Integrity API&#xff0c;可能会导致部分用户面临无法使用某些App的窘境。Play Integrity API是Google提供给开发者的工具&#xff0c;用于验证App是否在“未修改”的设备上运行。 许多重要应用…...

深度学习篇---人脸识别中的face-recognition库和深度学习

深度学习方法和使用 Python 的face_recognition库进行人脸识别在技术原理、实现方式和应用场景上有显著区别&#xff0c;以下从多个维度对比分析&#xff1a; 一、技术原理 1. 深度学习方法 核心逻辑&#xff1a;基于神经网络&#xff08;如卷积神经网络 CNN&#xff09;构建…...

(11)java+ selenium->元素定位之By_tag_name

1.简介 继续WebDriver关于元素定位,这篇介绍By ClassName。tagName是DOM结构的一部分,其中页面上的每个元素都是通过输入标签,按钮标签或锚定标签等标签定义的。每个标签都具有多个属性,例如ID,名称,值类等。就其他定位符而言在Selenium中,我们使用了标签的这些属性值来…...

React---day5

4、React的组件化 组件的分类&#xff1a; 根据组件的定义方式&#xff0c;可以分为&#xff1a;函数组件(Functional Component )和类组件(Class Component)&#xff1b;根据组件内部是否有状态需要维护&#xff0c;可以分成&#xff1a;无状态组件(Stateless Component )和…...

Java开发之定时器学习

面试 一、线程池实现定时器 核心代码&#xff1a; public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(5);Runnable runnable () -> System.out.println("当前线程"Thread.current…...

HealthBench医疗AI评估基准:技术路径与核心价值深度分析(上)

引言:医疗AI评估的新范式 在人工智能技术迅猛发展的当下,医疗AI系统已逐渐从实验室走向临床应用。然而,医疗领域的特殊性要求这些系统不仅需要在技术指标上表现出色,更需要在实际临床场景中展现出可靠、安全且有效的性能。长期以来,医疗AI评估领域面临着三个核心挑战:评…...

Windows+VSCode搭建小智(xiaozhi)开发环境

作为一名DIY达人&#xff0c;肯定不会错过最近很火的“小智AI聊天机器人”&#xff0c;网上教程非常丰富&#xff0c;初级玩家可以直接在乐鑫官方下载ESP-IDF安装包并经过简单的菜单式配置后&#xff0c;即可进行代码编译和烧录&#xff08;详见&#xff1a;Docs&#xff09;。…...

VueScan Pro v9.8.45.08 一款图像扫描软件,中文绿色便携版

VueScan是著名的第三方底片扫描仪驱动程序&#xff0c;支持市场可见绝大多数型号的底片扫描仪&#xff0c;可以更为灵活地控制扫描过程&#xff0c;更深入地发掘硬件潜力&#xff0c;获取色彩 完美的高质量扫描结果。VueScan支持200种以上的底片类型&#xff0c;在剪取图像时制…...

FreeRTOS通俗理解指南:基础概念 + 架构+ 内核组件+练手实验

RTOS 基础概念 想象一下&#xff0c;你是一个忙碌的厨师&#xff0c;在厨房里同时要完成煎牛排和煮意大利面两项任务。 1.传统单线程模式&#xff08;没有RTOS&#xff09; 如果你只能按顺序一项一项地做&#xff0c;就会是这样的过程&#xff1a; 先煎一会儿牛排然后去看看…...

Python后端开发实战:从0到1搭建高可用API服务

引言 Python凭借其简洁的语法和丰富的生态(如Django、Flask、FastAPI等框架),已成为后端开发的主流语言之一。本文将结合一个真实电商API项目,分享从架构设计到部署上线的完整流程,并总结开发过程中常见的坑与最佳实践。 一、实战案例:电商API开发流程 1.1 技术选型 框…...

房屋租赁系统 Java+Vue.js+SpringBoot,包括房屋信息、看房申请、租赁合同、房屋报修、收租信息、维修数据、租客管理、公告管理模块

房屋租赁系统 JavaVue.jsSpringBoot&#xff0c;包括房屋信息、看房申请、租赁合同、房屋报修、收租信息、维修数据、租客管理、公告管理模块 百度云盘链接&#xff1a;https://pan.baidu.com/s/16YRGBPsfbd4_HxXhO0jM5Q 密码&#xff1a;smk4 摘 要 房屋是人类生活栖息的重要…...

4、ubuntu系统 | 文本和目录操作函数

1、目录操作函数 ls&#xff08;列出目录内容&#xff09; 用途&#xff1a;列出指定目录中的文件和子目录。语法&#xff1a;ls [选项] [路径]常用选项&#xff1a; -l&#xff1a;以长格式显示文件详细信息&#xff08;权限、所有者、大小、时间等&#xff09;。-a&#xff…...

docker部署ELK,ES开启安全认证

ES启动命令 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:8.17.0 es启动之后需要进入es容器&#xff0c;重置密码 elasticsearch-reset-password -u elastic -i 重置后的密码配置到kibana.yml中&#xff0c;启动kibana docker run …...

ASP.NET MVC添加视图示例

ASP.NET MVC高效构建Web应用- 商品搜索 - 京东 视图&#xff08;V&#xff09;是一个动态生成HTML页面的模板&#xff0c;它负责通过用户界面展示内容。本节将修改HelloWorldController类&#xff0c;并使用视图模板文件&#xff0c;以干净地封装生成对客户端的HTML响应的过程…...