最近在学Qt。学东西怎么能不动手。

就写了些小程序。看QQ截图能够动态吸附直线的功能挺有意思,所以就模仿了一个。

先上效果图

界面很简单。。呵呵

移动鼠标,会把鼠标所在最小矩形选中。把没有选中的地方给模糊化,以示我们选中的区域很清楚。

还可以选中窗口中控件的区域。

小菜单

截图效果

编程思路:

1.动态找到鼠标所在区域的矩形,肯定是要获得桌面上每个窗口以及其子控件的大小位置属性。

想获得这些属性Qt貌似没有提供相关的API,只能用windows的API  EnumWindows 和 EnumChildWindows枚举出所有的窗口的位置坐标和大小属性保存在 一个vector中。

2.有了位置和大小(保存在一个Rect中就行了)就好办了。重写Qt的鼠标移动事件,自己定义了一个结构体

struct MyRect
{QRect myRect_; //矩形int distance;   //鼠标当前点到 所有边的距离之和,用于比较
};

每当鼠标移动就把每个包含鼠标当前点的矩形保存到myRect_中并且计算他的大小distance。

然后找到最小的distance对应的矩形。这个就是上图我们要显示的矩形了。

3.该怎么处理??Qt你们都晓得把。

我是通过QPixmap类的grabWindow 获得整个屏幕,然后 组合绘图 变色整个屏幕。

当鼠标移动到某个区域时 把这个区域 清晰显示。即上图效果。

4.保存图片QPixmap的save即可。

说了这么多了上代码把。

CPP。

#include "imagewidget.h"
#include <QPainter>
#include <QColor>
#include <QMessageBox>
#include <QByteArray>
#include <QBuffer>
#include <QPainter>
#include <QDesktopWidget>
#include <QPen>#include <Windows.h>
#include <vector>std::vector<QRect> allWindowRect;      //用于存储所有的窗口
std::vector<HWND> allWindowHwnd;      //用于存储所有的窗口句柄
std::vector<MyRect> myRectRestlt;     // 找到所有包含 鼠标当前移动点的矩形,并保存其到各边的距离之和。//声明回调函数
bool CALLBACK MyEnumWindowsProc(HWND hwnd,LPARAM lParam);ImageWidget::ImageWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);//用于获取窗口大小QDesktopWidget *dtw = QApplication::desktop(); //获得 整个屏幕pixmap_ = pixmap_.grabWindow(QApplication::desktop()->winId(),0,0,dtw->width(),dtw->height());isPressed = false;isDragging = false;captureMenu_ = new CaptureMenu();//打开鼠标 跟踪setMouseTracking(true);//关联 用于保存文件名connect(captureMenu_,SIGNAL(toSaveFile(QString)),this,SLOT(slotGetFileName(QString)));//遍历窗口 获得各个窗口的大小::EnumWindows((WNDENUMPROC)MyEnumWindowsProc,0);
}ImageWidget::~ImageWidget()
{
}
void ImageWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);pixmap_ = pixmap_.scaled(width(),height(),Qt::KeepAspectRatio);//pixmap_没有 alpha通道 添加通道QPixmap temp(pixmap_.size());temp.fill(Qt::transparent);QPainter p(&temp);p.setCompositionMode(QPainter::CompositionMode_Source);p.drawPixmap(0, 0, pixmap_);p.setCompositionMode(QPainter::CompositionMode_DestinationIn);p.fillRect(temp.rect(), QColor(50, 50, 50, 100)); //把图片调 暗 以显示截图全屏
//  pixmap_ = temp;//水印????painter.drawPixmap(0,0,temp);QPen penWather;penWather.setWidth(10);penWather.setBrush(QColor(125,125,125,125));painter.setPen(penWather);QString tempStr;tempStr = QString(tr("开始按钮X:%1 Y:%2 移动中的X:%3 Y:%4")).arg(pStart_.x()).arg(pStart_.y()).arg(pMove_.x()).arg(pMove_.y());painter.drawText(100,100,tempStr);//显示 截图拖动的区域QPen pen;pen.setWidth(5);pen.setColor(QColor(0,255,255,127));painter.setPen(pen);if (isDragging){painter.drawPixmap(pStart_.x(),pStart_.y(),pixmap_,pStart_.x(),pStart_.y(),pMove_.x()-pStart_.x(),pMove_.y()-pStart_.y());painter.drawRect(pStart_.x()-2,pStart_.y()-2,pMove_.x()-pStart_.x()-2,pMove_.y()-pStart_.y()-2);}else {painter.drawPixmap(miniRect.myRect_.left(),miniRect.myRect_.top(),pixmap_,miniRect.myRect_.left(),miniRect.myRect_.top(),miniRect.myRect_.width(),miniRect.myRect_.height());painter.drawRect(miniRect.myRect_.left()-2, miniRect.myRect_.top()-2, miniRect.myRect_.width()-2, miniRect.myRect_.height()-2);}
}
void ImageWidget::mousePressEvent(QMouseEvent *event)
{pStart_.setX(event->x());pStart_.setY(event->y());isPressed = true;
}void ImageWidget::mouseMoveEvent(QMouseEvent *event)
{if (isPressed)     //如果按下 鼠标 开始 区域截图{isDragging = true;pMove_.setX(event->x());pMove_.setY(event->y());}else            //如果没有按下鼠标 开始自动寻找合适窗口  //、应该改为 找到距离最近的 矩形块 。。。!!!!!!{//每次移动都清空myRectRestlt.clear();for (std::vector<QRect>::iterator it = allWindowRect.begin()+1;it != allWindowRect.end();it++){if (it->contains(event->x(),event->y())){calculateRectDistance(*it);}}MyRect tempMinRect;for(std::vector<MyRect>::iterator it = myRectRestlt.begin();it != myRectRestlt.end();it++){if (it->distance < tempMinRect.distance)    //找到最小的矩形{tempMinRect = *it;       //}}miniRect = tempMinRect;}update();
}
void ImageWidget::mouseReleaseEvent(QMouseEvent *event)
{//记录 结束点if (isDragging){pEnd_.setX(event->x());pEnd_.setY(event->y());}else{pStart_.setX(miniRect.myRect_.left());pStart_.setY(miniRect.myRect_.top());pEnd_.setX(miniRect.myRect_.right());pEnd_.setY(miniRect.myRect_.bottom());}isPressed = false;//isDragging = false;//新建菜单窗口captureMenu_->move(event->x()-152,event->y());captureMenu_->setWindowFlags(Qt::FramelessWindowHint);captureMenu_->exec();//退出窗口close();//发射 信号给截图软件窗口 可以显示emit beVisible();}
//回调函数
bool CALLBACK MyEnumWindowsProc(HWND hwnd,LPARAM lParam)
{if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd)){RECT tempRect;QRect tempQRect;::GetWindowRect(hwnd,&tempRect);tempQRect.setTopLeft(QPoint(tempRect.left,tempRect.top));tempQRect.setBottomRight(QPoint(tempRect.right,tempRect.bottom));allWindowRect.push_back(tempQRect);allWindowHwnd.push_back(hwnd);::EnumChildWindows(hwnd,(WNDENUMPROC)MyEnumWindowsProc,0);}return true;
}
void ImageWidget::slotGetFileName(QString filename)
{pixmapSave_ = pixmap_.copy(pStart_.x(),pStart_.y(),pEnd_.x()-pStart_.x(),pEnd_.y()-pStart_.y());//保存截图QByteArray bytes;//用于存放2进制数据QBuffer buffer(&bytes); //设置缓存buffer.open(QIODevice::ReadOnly);pixmapSave_.save(filename,"PNG",1);}
void ImageWidget::calculateRectDistance(QRect rect)
{int dis = rect.width() + rect.height();MyRect tempMyRect;tempMyRect.myRect_ = rect;tempMyRect.distance = dis;//添加进入myRectRestlt.push_back(tempMyRect);
}

。H

#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H#include <QWidget>
#include "ui_imagewidget.h"
#include <QPixmap>
#include <QPoint>
#include <QMouseEvent>
#include <capturemenu.h>
#include <QRect>struct MyRect
{QRect myRect_; //矩形int distance;   //鼠标当前点到 所有边的距离之和,用于比较
};class ImageWidget : public QWidget
{Q_OBJECTpublic:ImageWidget(QWidget *parent = 0);~ImageWidget();void paintEvent(QPaintEvent *event);//重写 鼠标按下 事件,记录截图起始点void mousePressEvent(QMouseEvent *event);//重写 鼠标松下 事件,记录截图结束点void mouseReleaseEvent(QMouseEvent *event);//重写 鼠标移动 事件,当拉动截图区域时 改变截图区域为正常图片(非蒙尘)void mouseMoveEvent(QMouseEvent *event);//用于计算 鼠标当前点到各个边的距离之和void calculateRectDistance(QRect rect);
private:Ui::ImageWidget ui;QPixmap pixmap_; //用于显示 截的整个屏幕QPixmap pixmapSave_; //用于 保存截图QPoint pStart_;  //记录开始截图位置QPoint pEnd_; //记录结束截图位置QPoint pMove_;    //记录移动中的坐标bool isPressed;   //是否按下按钮bool isDragging;    //是否用户拖选MyRect miniRect;    //最小矩形CaptureMenu *captureMenu_;    //截图结束时的菜单QString fullPath; //保存文件名以及 路径public slots:void slotGetFileName(QString filename);signals:void beVisible();  //给 截图软件发射可见 信号
};#endif // IMAGEWIDGET_H

贴了2个最重要的文件。

应届生刚入职在实习,公司让学Qt,学了半个月,代码写的不好的地方或者大家有更好的做法希望大家多多指教,注释很详细。

下载:http://download.csdn.net/detail/kfbyj/6713861


Qt 模仿QQ截图 动态吸附直线相关推荐

  1. Qt模仿QQ聊天窗口界面(二)

    Qt模仿QQ聊天窗口界面(二) Qt模仿QQ聊天窗口界面(二) 简述 修改 效果图 后期规划 代码 结尾 简述 在上篇我们已经搭好了QQ聊天窗口的框架,这里在原来的基础上叠加功能,以及优化一些控件. ...

  2. Qt模仿QQ聊天窗口界面(三)

    Qt模仿QQ聊天窗口界面(三)- 截图 Qt模仿QQ聊天窗口界面(三)- 截图 简述 效果图 代码篇 后期规划 结尾 简述 此篇在原来的基础上增加了QQ截图功能.在一个大佬的基础上进行了二次开发. 参 ...

  3. Qt模仿QQ聊天窗口界面(一)

    Qt模仿QQ聊天窗口界面(一) Qt模仿QQ聊天窗口界面(一) 简述 效果图 QQ的聊天窗口 我做的效果图 代码篇 结尾 简述 最近利用业余时间,模仿QQ做了一个聊天窗口界面,功能还不全,准备分几个部 ...

  4. Qt模仿QQ聊天窗口(四)

    Qt模仿QQ聊天窗口-气泡聊天消息 Qt模仿QQ聊天窗口-气泡聊天消息 简述 效果图 相关博客 代码 结尾 简述 最近感冒了,头疼,头疼,头疼.好了,进入正题吧,基本的气泡消息展示做好了,支持图文混排 ...

  5. Qt仿QQ截图最新版本,放大镜、坐标、颜色复制、画图形、文字、箭头、马赛克、序号都有,支持颜色面板,支持拖动和修改,支持撤销、钉住、屏幕录制

    史上最完整的QQ截图工具,1比1,高仿供学习,MulanPSL-2.0协议,Qt实现,可移植国产系统UOS/麒麟. 仿最新版QQ截图工具,功能完善. 文章目录 功能 效果 源码 使用 功能 支持窗口自 ...

  6. Qt模仿QQ登录界面(一)

    这两天研究qt,练习时做了个仿QQ登录界面,我这次实现的比较简单,先在这里记录一下,以后有空了会继续完善的. (一)效果图 这里使用我的qq号测试的如图: (二)工程文件 (三)代码实现 mainwi ...

  7. Qt模仿QQ聊天窗口合并功能

    模拟qq打开聊天窗口,打开多个聊天窗口时,窗口合并 效果图如下: 实现机制 聊天窗口放在QStackedWidget里管理,聊天条目放在QLIstWidget管理,通过QListWidget的item ...

  8. Qt仿QQ截图之QTextEdit宽高自适应

    之前用Qt做了个截图工具,最值得一写的就是在图片中添加文字时,如何让QTextEdit自适应文本的宽高 值得参考的是这篇博客:https://blog.csdn.net/kaida1234/artic ...

  9. Qt实现QQ截图中的马赛克效果

    一.效果 二.原理 对于截图类工具,虽然有撤销功能,但是画图形.写文字等操作应该不是在原图上直接操作的.通常的做法有两种,一是在原图窗口上覆盖一层透明的窗口,所有的操作都在这层透明窗口上进行,最终保存 ...

最新文章

  1. git 裁切_裁切参数设计(DOE试验)
  2. 怎么用python画个电脑_python语言还是java如何用python画爱心
  3. mysql search yum_centos7通过yum安装mysql的方法
  4. 如何评估深度学习模型效果?阿里工程师这么做
  5. no signatures that match those in shared user android.uid.system; ignoring!
  6. SAP Cloud for Customer UI Designer里如何消费Object Value Selector(OVS)
  7. mysql存储过程中怎么睡几秒_MySql的逻辑架构
  8. 数字U家,即刻出发!2022联合利华黑客马拉松报名倒计时!
  9. leetcode 509. 斐波那契数(Fibonacci Number)
  10. node.js 设置 淘宝 镜像
  11. 网站微信扫码登录回调不跳转问题
  12. nodejs 查看下载文件路径_Python + selenium + Chrome 模拟登陆QQ邮箱,批量下载附件,本地重命名
  13. About Endian
  14. Win10下安装配置使用WSL2
  15. iphone6 问题总结
  16. 数据分析实战之超市零售分析(附python代码)
  17. 【软件工程】-软件过程
  18. React Native学习-第一篇
  19. python话费充值_用Python方法查询移动手机余额话费的源码示例
  20. 独家微信域名封杀检测接口

热门文章

  1. kmplayer电脑版下载 | 作者是韩国的姜龙喜 | 后起之秀potplayer也是他的力作
  2. Vue - tabbar(底部导航栏)
  3. 智能家居中的毫米波雷达人体存在传感器
  4. Linux上快速入门英特尔Optane DC Persistent Memory Module的配置与使用
  5. 服务器运维协议,服务器维护委托合同
  6. 用animation实现钟表动画
  7. Redis实战学习--缓存首页图标类型
  8. python奇数偶数机器语言_python 学习笔记之基础1
  9. Python刷题记录(81-90)
  10. windows 运行bat文件,不弹出DOS界面