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();
    // 水平容器Widget
    buttonContainer = new QWidget(this);
    // 容器的大小
    buttonContainer->setGeometry(0, 0, 180, 30);

    // 创建水平布局并绑定容器widget
    layout = new QHBoxLayout(buttonContainer);
    // 创建确认和取消按钮
    m_confirmButton = new QPushButton("确认", this);
    m_cancelButton = new QPushButton("取消", this);

    // 设置按钮隐藏
    m_confirmButton->hide();
    m_cancelButton->hide();

    // 设置按钮的大小
    m_confirmButton->setFixedSize(80, 30);
    m_cancelButton->setFixedSize(80, 30);

    // 加入布局
    layout->addWidget(m_confirmButton);
    layout->addWidget(m_cancelButton);

    // 设置间隔为10
    layout->setSpacing(10);

    // 取消确认按钮函数
    connect(m_confirmButton, &QPushButton::clicked, this, &CaptureScreen::confirmCapture);
    connect(m_cancelButton, &QPushButton::clicked, this, &CaptureScreen::cancelCapture);
}

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();
        // 取消确认按钮隐藏
        m_confirmButton->hide();
        m_cancelButton->hide();
    }

    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;
    // 计算按钮显示位置
    int buttonX = selectedRect.right() - m_confirmButton->width() - m_confirmButton->width() - 10;
    int buttonY = selectedRect.bottom() + 5;
    if (buttonY + 30 > this->height())
    {
        buttonY = selectedRect.bottom() - m_confirmButton->height() - 5;
        buttonX = selectedRect.right() - m_confirmButton->width() - m_confirmButton->width() - 30;
    }
    if (buttonX < 0)
    {
        buttonX = 0;
    }
    // 设置按钮容器的位置
    buttonContainer->move(buttonX, buttonY);
    // 显示按钮
    m_confirmButton->show();
    m_cancelButton->show();
    return QWidget::mouseReleaseEvent(event);
}

// 绘制事件
void CaptureScreen::paintEvent(QPaintEvent *event)
{
    // 初始化 QPainter 对象 m_painter
    m_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);
    // 避免宽或高为零时拷贝截图有误,设置最小为1
    if (selectedRect.width() == 0)
    {
        selectedRect.setWidth(1);
    }
    if (selectedRect.height() == 0)
    {
        selectedRect.setHeight(1);
    }
    // 返回矩形对象
    return selectedRect;
}
// 确认截图
void CaptureScreen::confirmCapture()
{
    // 保存路径
    QString savePath = initBmpSavePath;
    if (!m_capturePixmap.isNull()) {
        // 保存为 BMP 格式
        m_capturePixmap.save(savePath, "BMP");
    }

    // 发送截图完成信号
    emit signalCompleteCature(m_capturePixmap);
    hide();
    emit capture_close();
}

// 取消截图
void CaptureScreen::cancelCapture()
{
    // 隐藏按钮
    m_confirmButton->hide();
    m_cancelButton->hide();

    // 隐藏截图窗口
    hide();
    emit capture_close();
}

CaptureScreen类.h

#ifndef CAPTURESCREEN_H
#define CAPTURESCREEN_H

#include <QWidget>
#include <QPainter>

class CaptureScreen : public QWidget
{
    Q_OBJECT

public:
    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:
    QWidget* buttonContainer;// 容器
    QHBoxLayout* layout;// 水平布局
    QPushButton *m_confirmButton;// 确认按钮
    QPushButton *m_cancelButton;// 取消按钮
    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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值