该截屏软件默认自定义截取屏幕,该程序保存地址为固定地址,读者可以改为自定义保存地址和重命名,也可以增加一个选项选择是截全屏还是自定义截屏
先上代码(主函数没有改动)
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDesktopWidget>
#include <QGuiApplication>
#include <QScreen>
#include <QPixmap>
#include <QMouseEvent>
#include <QLabel>
#include <QPainter>
#include <QPoint>
#include <QRect>
#include <QFileDialog>
#include <QDebug>
#include <QEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
virtual void closeEvent(QCloseEvent *event) override;
private:
Ui::Widget *ui;
QPoint startPoint;
QPoint endPoint;
QRect selectRect;
bool isSelect;
QPixmap fullScreenPixMap;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
isSelect = false;
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
setAttribute(Qt::WA_TranslucentBackground);
setGeometry(QApplication::desktop()->geometry());
QScreen *screen = QGuiApplication::primaryScreen();
if(screen)
{
fullScreenPixMap = screen->grabWindow(0);
}
}
Widget::~Widget()
{
delete ui;
}
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
startPoint = event->pos();
endPoint = startPoint;
isSelect = true;
grabMouse();
update();
}
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(isSelect)
{
endPoint = event->pos();
update();
}
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton && isSelect)
{
endPoint = event->pos();
isSelect = false;
releaseMouse();
selectRect = QRect(startPoint,endPoint).normalized();
QScreen *screen = QGuiApplication::primaryScreen();
if(screen)
{
QPixmap screens = screen->grabWindow(0);
QPixmap copped = screens.copy(selectRect);
copped.save("D:/sn.png");
}
close();
}
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.drawPixmap(0,0,fullScreenPixMap);
if(isSelect)
{
QRect rect(startPoint,endPoint);
rect = rect.normalized();
painter.setPen(Qt::DashLine);
painter.setBrush(QColor(0,0,0,100));
painter.drawRect(rect);
}
}
void Widget::closeEvent(QCloseEvent *event)
{
releaseMouse();
QApplication::quit();
QWidget::closeEvent(event);
}
原理
先获取全屏截图:在构造函数中,使用QScreen::grabWindow(0)抓取整个屏幕截图并将截图存储在fullScreenPixmap中。通过设置窗口标志Qt::FramelessWindowHint、Qt::QWindowStayOnTopHint和Qt::Tool以及属性Qt::WA_TranslucentBackground,创建一个全透明的窗口
绘制选择区域:在paintEvent中,先绘制全屏截图,然后在截图上绘制用户选择区域(这一步是为了防止其他窗口干扰截图鼠标事件)
保存选择区域:在mouseReleaseEvent中,根据用户选择区域从全屏截图中裁剪出选择区域的截图,并保存到文件