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

qt学习:截图+键盘事件

效果

  • 生成一个透明无边框全屏的窗口,然后按ctrl+b键就可以选择区域进行截图保存

步骤

  • 新建一个项目
  • 新建一个ctrlb类继承QMainWindow
  • 新建一个CaptureScreen类继承QWidget
  • 在main中启动ctrlb类

代码

ctrlb类.cpp

#include "ctrlb.h"
#include "capturescreen.h"
#include <QKeyEvent>
#include <QPixmap>
#include <QFileDialog>
#include <QProcess>
#include <QDebug>
#include <QFile>
#include <QTextStream>ctrlb::ctrlb(QWidget *parent): QMainWindow(parent) {}// 按键事件
void ctrlb::keyPressEvent(QKeyEvent *event) {if (event->key() == Qt::Key_B && event->modifiers() == Qt::ControlModifier) {triggerScreenshot();}
}
// 截图操作
void ctrlb::triggerScreenshot() {// 定义截图对象CaptureScreen *capture = new CaptureScreen();// 调用 close() 函数或用户点击关闭按钮时,窗口对象会被自动销毁capture->setAttribute(Qt::WA_DeleteOnClose); // 当完成截图操作后,会发送信号触发保存图片connect(capture, &CaptureScreen::signalCompleteCature, this, &ctrlb::handleScreenshot);// 显示截图窗口capture->show(); 
}
// 保存图片,参数是屏幕的截图
void ctrlb::handleScreenshot(const QPixmap &screenshot) {// 判断参数是否为空if (!screenshot.isNull()) {QString savePath =  "check.jpg";if (!savePath.isEmpty()) {// 保存为用户指定的文件screenshot.save(savePath, "JPG"); }}}

ctrlb类.h

#ifndef CTRLB_H
#define CTRLB_H#include <QMainWindow>class ctrlb : public QMainWindow
{Q_OBJECT
public:explicit ctrlb(QWidget *parent = nullptr);protected:void keyPressEvent(QKeyEvent *event) override;private:void triggerScreenshot();private slots:// 保存图片槽函数void handleScreenshot(const QPixmap &screenshot); 
};#endif // CTRLB_H

CaptureScreen类.cpp

#include "capturescreen.h"
#include <QApplication>
#include <QMouseEvent>
#include <QPixmap>
#include <QScreen>CaptureScreen::CaptureScreen(QWidget *parent): QWidget(parent), m_isMousePress(false)
{// 初始化窗口initWindow();//loadBackgroundPixmap();
}CaptureScreen::~CaptureScreen()
{}void CaptureScreen::initWindow()
{// 启用鼠标跟踪,移动的时候也会触发事件this->setMouseTracking(true);// 设置窗口为无边框模式this->setWindowFlags(Qt::FramelessWindowHint);// 设置窗口全屏显示setWindowState(Qt::WindowActive | Qt::WindowFullScreen);
}
// 抓取当前桌面内容作为背景快照
void CaptureScreen::loadBackgroundPixmap()
{// 获取当前主屏幕的 QScreen 对象QScreen *screen = QGuiApplication::primaryScreen();if (screen) {// 获取现在的整个屏幕m_loadPixmap = screen->grabWindow(0);}// 获取屏幕宽高m_screenwidth = m_loadPixmap.width();m_screenheight = m_loadPixmap.height();
}// 处理鼠标左键按下,记录起点位置
void CaptureScreen::mousePressEvent(QMouseEvent *event)
{// 判断是不是左键if (event->button() == Qt::LeftButton){// 画图标志m_isMousePress = true;// 记录起始位置m_beginPoint = event->pos();}return QWidget::mousePressEvent(event);
}// 处理鼠标移动,记录终点位置
void CaptureScreen::mouseMoveEvent(QMouseEvent* event)
{// 判断是否画图if (m_isMousePress){// 记录移动位置m_endPoint = event->pos();// 画矩形update();}return QWidget::mouseMoveEvent(event);
}// 处理鼠标松开,记录终点位置
void CaptureScreen::mouseReleaseEvent(QMouseEvent *event)
{// 记录结束位置m_endPoint = event->pos();// 结束画矩形m_isMousePress = false;return QWidget::mouseReleaseEvent(event);
}// 绘制事件
void CaptureScreen::paintEvent(QPaintEvent *event)
{// 初始化 QPainter 对象 m_painterm_painter.begin(this);// 半透明的黑色阴影,用于覆盖整个屏幕QColor shadowColor = QColor(0, 0, 0, 100);// 设置画笔m_painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap));// 将获取到的屏幕放到窗口上m_painter.drawPixmap(0, 0, m_loadPixmap);// 绘制一个半透明的黑色矩形m_painter.fillRect(m_loadPixmap.rect(), shadowColor);// 如果鼠标正在移动,会绘制选中的矩形区域if (m_isMousePress){// 计算选区矩形QRect selectedRect = getRect(m_beginPoint, m_endPoint);// 保存选区内容m_capturePixmap = m_loadPixmap.copy(selectedRect);// 将选区内容绘制到窗口m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap);// 绘制选区边框m_painter.drawRect(selectedRect);}// 释放对象m_painter.end();  //重绘结束;
}// 键盘事件
void CaptureScreen::keyPressEvent(QKeyEvent *event)
{// Esc 键退出截图;if (event->key() == Qt::Key_Escape){close();}// Enter键完成截图;if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter){// 保存截图为 JPG 格式QString savePath = "screenshot.jpg";if (!m_capturePixmap.isNull()) {// 保存为 JPG 格式m_capturePixmap.save(savePath, "JPG");}// 发送截图完成信号emit signalCompleteCature(m_capturePixmap);close();}
}// 计算一个矩形区域并返回
QRect CaptureScreen::getRect(const QPoint &beginPoint, const QPoint &endPoint)
{// 矩形的左上角坐标、宽度和高度int x, y, width, height;width = qAbs(beginPoint.x() - endPoint.x());height = qAbs(beginPoint.y() - endPoint.y());x = beginPoint.x() < endPoint.x() ? beginPoint.x() : endPoint.x();y = beginPoint.y() < endPoint.y() ? beginPoint.y() : endPoint.y();//  创建矩形对象QRect selectedRect = QRect(x, y, width, height);// 避免宽或高为零时拷贝截图有误,设置最小为1if (selectedRect.width() == 0){selectedRect.setWidth(1);}if (selectedRect.height() == 0){selectedRect.setHeight(1);}// 返回矩形对象return selectedRect;
}

CaptureScreen类.h

#ifndef CAPTURESCREEN_H
#define CAPTURESCREEN_H#include <QWidget>
#include <QPainter>class CaptureScreen : public QWidget
{Q_OBJECTpublic:CaptureScreen(QWidget *parent = 0);~CaptureScreen();Q_SIGNALS:void signalCompleteCature(QPixmap catureImage);private:void initWindow();void loadBackgroundPixmap();void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent* event);void mouseReleaseEvent(QMouseEvent *event);void keyPressEvent(QKeyEvent *event);void paintEvent(QPaintEvent *event);QRect getRect(const QPoint &beginPoint, const QPoint &endPoint);private:bool m_isMousePress;// 判断鼠标是否移动和是否画矩形QPixmap m_loadPixmap;// 整个屏幕的图像QPixmap m_capturePixmap;// 框选的屏幕图像int m_screenwidth;// 屏幕的宽int m_screenheight;// 屏幕的高QPoint m_beginPoint, m_endPoint;// 起点和结束点坐标QPainter m_painter;// 画图对象
};#endif // CAPTURESCREEN_H

main

#include "mainwindow.h"#include <QApplication>
#include "ctrlb.h"
#include <QDebug>
#include <QWidget>int main(int argc, char *argv[])
{QApplication a(argc, argv);qDebug()<<"init";ctrlb w;// 设置无边框窗口w.setWindowFlags(Qt::FramelessWindowHint); // 全屏w.showFullScreen();// 背景透明w.setAttribute(Qt::WA_TranslucentBackground);// 设置透明度w.setWindowOpacity(1); w.show();return a.exec();
}

相关文章:

qt学习:截图+键盘事件

效果 生成一个透明无边框全屏的窗口&#xff0c;然后按ctrlb键就可以选择区域进行截图保存 步骤 新建一个项目新建一个ctrlb类继承QMainWindow新建一个CaptureScreen类继承QWidget在main中启动ctrlb类 代码 ctrlb类.cpp #include "ctrlb.h" #include "cap…...

Scala中Arry

import scala.collection.mutable.ArrayBuffer //Arry:数组 //可修改的&#xff1a;ArryBuffer //不可修改的&#xff1a;Arryobject Test_1118_2 {//可修改的&#xff1a;ArrayBufferdef main(args: Array[String]): Unit {//1.新建val arr1ArrayBuffer(1,2,3)//2.添加arr14a…...

学习threejs,使用AnimationMixer实现变形动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.AnimationMixer 动画…...

两大新兴开发语言大比拼:Move PK Rust

了解 Move 和 Rust 的差异有助于开发者根据项目的具体需求选择最合适的语言。选择不恰当的语言可能会导致项目后期出现技术债务。不同语言有其独特的优势。了解 Move 和 Rust 的差异可以帮助开发者拓展技术视野&#xff0c;发现不同语言在不同领域的应用潜力。 咱们直奔主题&a…...

基于一种基于OCR图像识别技术的发票采集管理系统及方法

本发明涉及了一种基于OCR图像识别技术的发票采集管理系统及方法&#xff0c;该系统的发票信息采集单元采集发票图片信息数据&#xff0c;OCR图像识别单元基于OCR图像识别技术并结合人工智能深度学习算法对发票图片信息数据进行识别读取以获得OCR图像识别结果&#xff0c;发票信…...

基于深度学习的车牌检测系统的设计与实现(安卓、YOLOV、CRNNLPRNet)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

JavaWeb——JS、Vue

目录 1.JavaScript a.概述 b.引入方式 c.JS的基础语法 d.JS函数 e.JS对象 f.JS事件监听 2.Vue a.概述 b.Vue常用指令 d.生命周期 1.JavaScript a.概述 JavaScript是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互。JavaScript和…...

Springboot 整合 Java DL4J 构建股票预测系统

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

ATmaga8单片机Pt100温度计源程序+Proteus仿真设计

目录 1、项目功能 2、仿真图 ​3、程序 资料下载地址&#xff1a;ATmaga8单片机Pt100温度计源程序Proteus仿真设计 1、项目功能 设计Pt100铂电阻测量温度的电路&#xff0c;温度测量范围是0-100摄氏度&#xff0c;要求LCD显示。画出电路图&#xff0c;标注元器件参数&am…...

FPGA通过MIPI CSI-2发送实时图像到RK3588,并HDMI显示

介绍FPGA通过MIPI CSI-2发送实时图像到RK3588&#xff0c;并HDMI显示。 FPGA本地产生动态图像模板&#xff0c;通过MIPI CSI-2接口发送到RK3588 MIPI CSI接口。RK3588注册成相机后&#xff0c;调用接口并在HDMI显示器上显示。 1、RK3588驱动调试 查看Media controller信息 Med…...

ELK8.15.4搭建开启安全认证

安装 Elastic &#xff1a;Elasticsearch&#xff0c;Kibana&#xff0c;Logstash 另外安装一个收集器filebeat 通过二进制安装包进行安装 创建一个专门放elk目录 mkdir /elk/ mkdir /elk/soft下载 es 、kibana、Logstash、filebeat二进制包 cd /elk/softwget https://art…...

原生微信小程序中封装一个模拟select 下拉框组件

1.首先在components 里面设置组件名称&#xff1a;van-select&#xff08;随便取名字&#xff09;&#xff1b; 2.新建文件写代码&#xff1a; wxml&#xff1a; <view class"w100 select_all_view"><!-- 标题&#xff0c;可以没有 --><view class…...

商品管理系统引领时尚零售智能化升级 降价商品量锐减30%

根据贝恩咨询公司2024年发布的消费品报告&#xff0c;当前消费品行业正面临增长放缓、全球市场波动及消费者期望变化的巨大压力。为保持市场竞争力&#xff0c;企业需要重新审视其增长战略&#xff0c;重视可持续创新、数字化转型和运营敏捷性。企业必须灵活应对供应链中断和消…...

UE5 5.1.1创建C++项目,显示error C4668和error C4067

因为工作要求&#xff0c;没法使用最新 5.5版本的ue5 而是要用ue5.1和5.2版本。 但是我在安装下载了visual studio2022后&#xff0c;使用 ue5.1编辑器 创建C项目&#xff0c;爆出如下错误。 error C4668: ?????__has_feature?????ΪԤ?????꣬???0????…...

spring boot 集成 redis 实现缓存的完整的例子

Cacheable 注解是 Spring Cache 抽象的一部分&#xff0c;用于声明式地管理缓存。Cacheable 注解本身并不直接指定缓存的存储位置&#xff0c;而是依赖于配置的缓存管理器&#xff08;CacheManager&#xff09;来决定缓存数据的存储位置。 常见的缓存存储方式: 1、内存缓存&a…...

json-bigint处理前端精度丢失问题

问题描述&#xff1a;前后端调试过程中&#xff0c;有时候会遇到精度丢失的问题&#xff0c;比如后端给过来的id超过16位&#xff0c;就会出现精度丢失的情况&#xff0c;前端拿到的id与后端给过来的不一致。 解决方案&#xff1a; 1、安装 npm i json-bigint 2、在axios中配置…...

【算法】【优选算法】前缀和(下)

目录 一、560.和为K的⼦数组1.1 前缀和1.2 暴力枚举 二、974.和可被K整除的⼦数组2.1 前缀和2.2 暴力枚举 三、525.连续数组3.1 前缀和3.2 暴力枚举 四、1314.矩阵区域和4.1 前缀和4.2 暴力枚举 一、560.和为K的⼦数组 题目链接&#xff1a;560.和为K的⼦数组 题目描述&#x…...

Node.js 23 发布了!

Node.js 23 现已推出&#xff0c;带来了新功能、性能改进和更好的开发者体验。此次版本提升了兼容性和稳定性&#xff0c;提供了更多工具来构建高效的应用程序。 此外&#xff0c;Node.js 22 将在 10 月 29 日当周被提升为长期支持 (LTS) 版本&#xff0c;进入长期维护阶段&am…...

如何通过低代码逻辑编排实现业务流程自动化?

随着数字化转型的加速&#xff0c;企业对高效、灵活的业务流程自动化需求日益增加。传统开发模式下的定制化解决方案往往周期长、成本高且难以适应快速变化的需求。低代码平台以其直观、简便的操作界面和强大的功能逐渐成为企业实现业务流程自动化的理想选择。本文将探讨低代码…...

thinkphp6模板调用URL方法生成的链接异常

var uul params.url ;console.log(params.url);console.log("{:Url(UserLog/index)}");console.log("{:Url("uul")}"); 生成的链接地址 UserLog/index /jjg/index.php/Home/UserLog/index.html /jjg/index.php/Home/Index/UserLog/index.html…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#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 …...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...