主要实现2 个功能点:
1 截图
2 窗口镂空
实现截图主要使用QGuiApplication::primaryScreen() 获取到QScreen ,然后调用QGuiApplication::grabWindow函数进行截图,代码示例:

QScreen* screen = QGuiApplication::primaryScreen();if(const QWindow* window = windowHandle()){screen = window->screen();}if(!screen)return;originalPixmap = screen->grabWindow(0,rc.left(),rc.top(),rc.right() - rc.left(),rc.bottom() - rc.top());
此时originalPixmap 就是 截取的图片,类型为QPixmap,可直接展示。
实现窗口局部透明,即窗口局部镂空。首先将窗口 搞成全透明,然后在未截图情况下,
绘制窗口背景为半透明;(为什么要先 将窗口弄成全透明那?
因为 不将窗口搞成全透明的话,后面绘制的半透明,
其实 还存在一个窗口背景。做不到真正意义上的全透明)
在截图的情况下将 截图区域不绘制,即全透明,然后绘制非截图区域为半透明。代码如下:
  if(type == QEvent::Paint){qDebug() << "start paint";QRect rc = ComputeRect(ptStart,ptEnd);QPainter painter(screenshot_dlg_);if(bCapStart){//设置mask 使当前区域全透明QPolygon polygon1;QRect screenRc = ScreenRect();painter.setBrush(QBrush(QColor(0,0,0,100)));painter.setPen(QPen(Qt::NoPen));polygon1 << QPoint(screenRc.left(),screenRc.top())<< QPoint(screenRc.right(),screenRc.top())<< QPoint(rc.right(),rc.top())<< QPoint(rc.left(),rc.top());painter.drawPolygon(polygon1);QPolygon polygon2;polygon2 << QPoint(screenRc.left(),screenRc.top())<< QPoint(screenRc.left(),screenRc.bottom())<< QPoint(rc.left(),rc.bottom())<< QPoint(rc.left(),rc.top());painter.drawPolygon(polygon2);QPolygon polygon3;polygon3 << QPoint(screenRc.left(),screenRc.bottom())<< QPoint(screenRc.right(),screenRc.bottom())<< QPoint(rc.right(),rc.bottom())<< QPoint(rc.left(),rc.bottom());painter.drawPolygon(polygon3);QPolygon polygon4;polygon4 << QPoint(screenRc.right(),screenRc.top())<< QPoint(screenRc.right(),screenRc.bottom())<< QPoint(rc.right(),rc.bottom())<< QPoint(rc.right(),rc.top());painter.drawPolygon(polygon4);}else{painter.setBrush(QBrush(QColor(0,0,0,100)));painter.drawRect(ScreenRect());}}
以上4个区域polygon1、polygon2、polygon3、polygon4 即为非截图区域,
我们把它搞成半透明,未绘制的就是全透明了(因为窗口就是全透的)。
完整代码如下:
window.h
    #ifndef WINDOW_H
#define WINDOW_H#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QPixmap>
#include <QDialog>
#include <QRect>
#include <QSizeGrip>class SceenShot:public QWidget
{public:SceenShot(QWidget* parent = Q_NULLPTR);void updateShowScreenshot();bool eventFilter(QObject *watched, QEvent *event) override;
protected:void resizeEvent(QResizeEvent *event) override;QRect ScreenRect();
public slots:void StartShotScreen();void ShootScreen(QRect& rc);
private:QRect ComputeRect(QPoint& pt1,QPoint& pt2);QDialog*    screenshot_dlg_;QPushButton* shot_screen_;QVBoxLayout* vbox_;QLabel* show_label_;QPixmap originalPixmap;//绘制截图窗口用的QPixmap*    m_Cache;QSizeGrip   m_SizeGrip;
};#endif // WINDOW_H

window.cpp

#include "window.h"
#include <QGuiApplication>
#include <QWindow>
#include <QScreen>
#include <QMouseEvent>
#include <QPainter>
#include <QPen>
#include <QDebug>
#include <QImage>
#include <QBitmap>SceenShot::SceenShot(QWidget* parent):QWidget(parent),m_SizeGrip(nullptr)
{m_Cache = nullptr;vbox_ = new QVBoxLayout(this);shot_screen_ = new QPushButton(tr("shootScreen"),this);shot_screen_->setShortcut(tr("ctrl+a"));show_label_ = new QLabel(this);show_label_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);show_label_->setAlignment(Qt::AlignCenter);show_label_->setMinimumSize(300,300);show_label_->setPixmap(originalPixmap);connect(shot_screen_,&QPushButton::clicked,this,&SceenShot::StartShotScreen);vbox_->addWidget(shot_screen_);vbox_->addWidget(show_label_);screenshot_dlg_ = new QDialog(this,Qt::FramelessWindowHint);screenshot_dlg_->setAttribute(Qt::WA_TranslucentBackground);screenshot_dlg_->hide();//给Dialog 安装事件过滤器screenshot_dlg_->installEventFilter(this);//this->setLayout(vbox_);
}void SceenShot::ShootScreen(QRect& rc)
{shot_screen_->setEnabled(false);QScreen* screen = QGuiApplication::primaryScreen();if(const QWindow* window = windowHandle()){screen = window->screen();}if(!screen)return;originalPixmap = screen->grabWindow(0,rc.left(),rc.top(),rc.right() - rc.left(),rc.bottom() - rc.top());updateShowScreenshot();shot_screen_->setEnabled(true);
}void SceenShot::updateShowScreenshot()
{show_label_->setPixmap(originalPixmap.scaled(show_label_->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}void SceenShot::resizeEvent(QResizeEvent *event)
{QSize scaledSize = originalPixmap.size();scaledSize.scale(show_label_->size(), Qt::KeepAspectRatio);if (!show_label_->pixmap() || scaledSize != show_label_->pixmap()->size())updateShowScreenshot();
}void SceenShot::StartShotScreen()
{//获取屏幕大小信息QScreen* primaryScreen = QGuiApplication::primaryScreen();QRect rect = primaryScreen->geometry();screenshot_dlg_->setGeometry(rect);screenshot_dlg_->show();
}bool SceenShot::eventFilter(QObject *watched, QEvent *event)
{static QPoint ptStart ={0,0};static QPoint ptEnd ={0,0};static bool bCapStart = false;QEvent::Type type =  event->type();QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);if(mouse_event && mouse_event->button() == Qt::LeftButton && type == QEvent::MouseButtonPress){//鼠标左键按下,记录按下位置bCapStart = true;ptStart = mouse_event->pos();}else if(mouse_event && mouse_event->button() == Qt::LeftButton && type == QEvent::MouseButtonRelease){//qDebug() << "MouseButtonRelease";bCapStart = false;QRect rc = ComputeRect(ptStart,ptEnd);qDebug() << "x:" << rc.left() << " y:" << rc.top() << " right:" << rc.right() << " bottom:" << rc.bottom();ShootScreen(rc);ptStart.setX(0);ptStart.setY(0);ptEnd.setX(0);ptEnd.setY(0);}else if(bCapStart && type == QEvent::MouseMove){ptEnd = mouse_event->pos();screenshot_dlg_->update();}//    //重写Dialog得绘制事件和改变大小事件
//    if(type == QEvent::Paint)
//    {//        if(m_Cache != NULL)
//          {//            QPainter painter(screenshot_dlg_);//            painter.drawPixmap(0, 0, *m_Cache);//        #if QT_VERSION >= 0x040500
//            if(!testAttribute(Qt::WA_TranslucentBackground)) screenshot_dlg_->setMask(m_Cache->mask());
//        #else
//            screenshot_dlg_->setMask(m_Cache->mask());
//        #endif
//          }
//    }
//    else if(type == QEvent::Resize)
//    {//        delete m_Cache;
//        m_Cache = new QPixmap(screenshot_dlg_->size());
//        m_Cache->fill(Qt::transparent);
//        QPainter painter(m_Cache);
//        QColor darkBlue ( 23,  23,  34);
//          QColor lightBlue(177, 177, 203);//          /********** Window's background **********/
//          QPolygon background;//          background << QPoint(           0,            16)
//                     << QPoint(          16,             0)
//                     << QPoint(width() -  1,             0)
//                     << QPoint(width() -  1, height() - 33)
//                     << QPoint(width() - 17, height() - 17)
//                     << QPoint(         272, height() - 17)
//                     << QPoint(         256, height() -  1)
//                     << QPoint(          16, height() -  1)
//                     << QPoint(          16,           272)
//                     << QPoint(           0,           256);//          painter.setPen  (QPen  (darkBlue));
//          painter.setBrush(QBrush(darkBlue));//          painter.drawPolygon(background);
//          /*****************************************///          /********** Window's frame **********/
//          QPolygon frame;//          frame << QPoint(           4,            20)
//                << QPoint(          20,             4)
//                << QPoint(width() -  4,             4)
//                << QPoint(width() -  4, height() - 37)
//                << QPoint(width() - 20, height() - 21)
//                << QPoint(         268, height() - 21)
//                << QPoint(         252, height() -  5)
//                << QPoint(          20, height() -  5)
//                << QPoint(          20,           268)
//                << QPoint(           4,           252);//          painter.setPen  (QPen(lightBlue));
//          painter.setBrush(Qt::NoBrush    );//          painter.drawPolygon(frame);
//          /*****************************************///          //m_SizeGrip.move  (width() - 32, height() - 49);
//          //m_SizeGrip.resize(          32,            32);
//    }if(type == QEvent::Paint){qDebug() << "start paint";QRect rc = ComputeRect(ptStart,ptEnd);QPainter painter(screenshot_dlg_);if(bCapStart){//设置mask 使当前区域全透明QPolygon polygon1;QRect screenRc = ScreenRect();painter.setBrush(QBrush(QColor(0,0,0,100)));painter.setPen(QPen(Qt::NoPen));polygon1 << QPoint(screenRc.left(),screenRc.top())<< QPoint(screenRc.right(),screenRc.top())<< QPoint(rc.right(),rc.top())<< QPoint(rc.left(),rc.top());painter.drawPolygon(polygon1);QPolygon polygon2;polygon2 << QPoint(screenRc.left(),screenRc.top())<< QPoint(screenRc.left(),screenRc.bottom())<< QPoint(rc.left(),rc.bottom())<< QPoint(rc.left(),rc.top());painter.drawPolygon(polygon2);QPolygon polygon3;polygon3 << QPoint(screenRc.left(),screenRc.bottom())<< QPoint(screenRc.right(),screenRc.bottom())<< QPoint(rc.right(),rc.bottom())<< QPoint(rc.left(),rc.bottom());painter.drawPolygon(polygon3);QPolygon polygon4;polygon4 << QPoint(screenRc.right(),screenRc.top())<< QPoint(screenRc.right(),screenRc.bottom())<< QPoint(rc.right(),rc.bottom())<< QPoint(rc.right(),rc.top());painter.drawPolygon(polygon4);}else{painter.setBrush(QBrush(QColor(0,0,0,100)));painter.drawRect(ScreenRect());}}return false;
}QRect SceenShot::ComputeRect(QPoint& pt1,QPoint& pt2)
{QRect rc;if(pt1.x() > pt2.x()){if(pt1.y() > pt2.y()){//pt1 为右下点rc.setTopLeft(pt2);rc.setBottomRight(pt1);}else{rc.setBottomLeft(pt2);rc.setTopRight(pt1);}}else{if(pt1.y() > pt2.y()){//pt1 为左下点rc.setBottomLeft(pt1);rc.setTopRight(pt2);}else{rc.setTopLeft(pt1);rc.setBottomRight(pt2);}}return rc;
}QRect SceenShot::ScreenRect()
{QScreen* screen = QGuiApplication::primaryScreen();return screen->geometry();
}

main.cpp

#include <QApplication>
#include "window.h"int main(int argc,char* argv[])
{QApplication app(argc,argv);SceenShot sc;sc.show();sc.resize(300,300);return app.exec();
}

以上就是简单的截图功能。使用鼠标拖拽截图。

qt 实现窗口局部镂空,并截图显示。相关推荐

  1. qt自定义窗口添加父窗口后,显示不出来

    提要 继承于QDialog的类,在被其它类创建的改对象时,没设置父窗口前显示正常,设置了父窗口后显示不出来. 自定义窗口的构造函数 configBtnNameDialog::configBtnName ...

  2. qt自定义窗口,其绘制的窗口边框线显示不全

    引言 自定义窗口,该窗口包含标题栏,默认整个窗口的边框线为蓝色,当点击该窗口的时候,窗口的边框线便为红色.程序在运行的时候,窗口的边框线只显示了左右两边的线,没有显示上下边的线. 示例 效果: 解决方 ...

  3. qt设置窗口不在任务栏上显示

    可以通过设置窗口标志来实现. 调用QWidget的setWindowFlags()函数. 设置为Qt::Tool.Qt::SubWindow. Qt::Popup可以达到目的. 但是这样做会有副作用: ...

  4. Qt设置窗口不在系统的任务栏上显示

    有时候有特殊需求,不希望在任务栏上出现应用程序的图标.该怎么办呢? 其实可以通过设置窗口标志来实现. 调用QWidget的setWindowFlags()函数. 设置为Qt::Tool.Qt::Sub ...

  5. qt获取窗口的右上角位置_如何获得 Qt窗口部件在主窗口中的位置--确定鼠标是否在某一控件上与在控件上的位置...

    用Qt Creator 设计程序时,最方便的就是ui设计器,可以很容易的得到想要的布局. 但是这样自动布局带来的后果是很难知道窗口中某一部件在主窗口中的相对位置. 在处理子窗口鼠标事件时变的很麻烦.主 ...

  6. linux 界面工具 qt,Qt主窗口中的工具栏

    工具栏类 QToolBar 快捷项 QAcitonQToolBar* tb = addToolBar("Tool Bar");//addToolBar是Qt主窗口的成员函数,在主窗 ...

  7. 使用Qt作窗口截屏(含源码)

    截屏(screenshot),就是将屏幕上的东西拷贝下来存成图片文件.介绍的好像有点多余:(,那我们就直接切入正题. QPixmap提供了两个函数grabWidget和grabWindow可以将屏幕上 ...

  8. python PyQt5 QMainWindow类(Qt主窗口框架,主窗口提供了用于构建应用程序用户界面的框架)

    https://doc.qt.io/qtforpython/PySide2/QtWidgets/QMainWindow.html?highlight=qmainwindow#PySide2.QtWid ...

  9. qt 子窗口与父窗口数据通信_Qt实例--主窗口和子窗口互发信号

    准备工作: 需要首先添加一个Qt设计师界面类,这里使用默认类名Form. 实例一:主窗口向子窗口发送信号 在主窗口添加一个按钮QPushButton,在子窗口添加一个标签QLabel. 主窗口添加一个 ...

最新文章

  1. java通过抛异常来返回提示信息
  2. vue、cnpm不是内部文件_vue文件通过cnpm install后无法用npm run serve打开
  3. 关于sqlite数据库在使用过程中应该注意以下几点
  4. 深度探索C++ 对象模型(6)-Data member的绑定
  5. 计算机视觉与深度学习 | 基于Matlab双目视觉之深度估计(视频中人到相机的距离)(附源代码)
  6. java ecc 加密_java-信息安全(十一)-非对称加密算法002-ECC,签名003-ECDSA签名
  7. P4900 食堂(数学式子推导)
  8. 后勤管理系统_充满“智慧”的后勤管理系统是什么样的?
  9. 一定要吃透的四个人性真相
  10. example datasets in sklearn
  11. 友盟ionic多渠道自动签名app
  12. zoj 3690(递推+矩阵优化)
  13. java--GUI窗口可视化编程1
  14. 如何在官网上下载MySQL驱动--最新方法
  15. PHP输出100以内的质数(包括普通写法和数组形式输出)
  16. 分享几款狂拽炫酷屌炸天的大屏监控场景案例
  17. matlab 温度计,Matlab与Excel相结合实现标准铂电阻温度计检定数据处理
  18. golang,Python,我们该怎么选
  19. ActiveMQ安装与使用总结
  20. fix feeds/telephony/net/freeswitch/Makefile

热门文章

  1. html5 lineheight属性,HTML中line-height的继承
  2. c语言s开头的函数以及作用,C语言函数大全-s开头-完整版.doc
  3. java protobuffer 网络_使用Protobuf定义网络协议
  4. android获取图片缩略图,Android系获取图片和视频的缩略图
  5. linux中光标向上调一行命令,Linux vi 中移动光标 命令
  6. apache 安装与配置详细教程
  7. 4.7 mini趴 走进猎豹
  8. Valid Sudoku leetcode java
  9. Java Bad version
  10. Android Android应用开发实战 学习总结杂项