QT截图程序,可多屏幕截图

截图程序,支持多屏幕时跨屏幕截图。截图使用setMask达到镂空效果,截图后会有预览和保存功能。截图时按下Esc可退出。

mainwindow.ui

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <QPushButton>
#include <QPixmap>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle(QString(tr("截图")));
    ui->centralwidget->setMouseTracking(true);
    ui->comboBox->addItem(QString(tr(".")));
    ui->comboBox->addItem(QString(tr("Select Folder")));
    connect(ui->comboBox, SIGNAL(activated(int)), this, SLOT(SelectFolder(int)));
    connect(ui->button_reset, SIGNAL(clicked(bool)), this, SLOT(ResetSnap(bool)));
    connect(ui->button_save, SIGNAL(clicked(bool)), this, SLOT(SavePicture(bool)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    qDebug()<<this->geometry();
    QMainWindow::mouseMoveEvent(event);
}

void MainWindow::SetImage(QPixmap &pixmap)
{
    const double defultWidth = 400.0;
    const double defaultHeight = 160.0;

    ui->label->setPixmap(pixmap);
    double pixscale = 1.0 * pixmap.width()/pixmap.height();
    double initscale = defultWidth/defaultHeight;
    if (pixscale > initscale)
    {
        ui->label->setFixedWidth(defultWidth);
        ui->label->setFixedHeight(defultWidth / pixscale);
    }
    else
    {
        ui->label->setFixedHeight(defaultHeight);
        ui->label->setFixedWidth(defaultHeight * pixscale);
    }
}

void MainWindow::SelectFolder(int index)
{
    if (index == 1)
    {
        qDebug()<<ui->comboBox->itemText(index);
        QString directory = QFileDialog::getExistingDirectory(this,
                                    tr("QFileDialog::getExistingDirectory()"),
                                    ".");
        if (!directory.isEmpty())
        {
            qDebug()<<directory;
            ui->comboBox->addItem(directory);
            ui->comboBox->setCurrentText(directory);
        }
        else
        {
            ui->comboBox->setCurrentIndex(0);
        }
    }
}

void MainWindow::ResetSnap(bool)
{
    this->hide();
    emit resetSnap();
}

void MainWindow::SavePicture(bool)
{
    if (ui->lineEdit->text().trimmed() == QString(""))
    {
        ui->lineEdit->setFocus();
        return;
    }
    if (ui->comboBox->currentText() != ".")
    {
        ui->label->pixmap()->save(ui->comboBox->currentText() + "/" + ui->lineEdit->text(), "PNG");
    }
    else
    {
        ui->label->pixmap()->save(ui->lineEdit->text(), "PNG");
    }
}

maskwidget.cpp

cpp 复制代码
#include "maskwidget.h"
#include "ui_maskwidget.h"
#include <QMouseEvent>
#include <QRegion>
#include <QScreen>
#include <QPainter>
#include <QGuiApplication>
#include <QPixmap>
#include <QDebug>
#include <QtMath>

MaskWidget::MaskWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MaskWidget)
{
    ui->setupUi(this);
    setMouseTracking(true);
    setWindowFlags(Qt::FramelessWindowHint);

    setWindowOpacity(0.8);
    QList<QScreen*> screens = QGuiApplication::screens();
    int width = 0;
    int height = 0;
    for (QScreen *screen : screens)
    {
        width += screen->geometry().width();
        if (height < screen->geometry().height())
        {
            height = screen->geometry().height();
        }
        qDebug()<<screen->geometry();
    }
    this->setFixedSize(width, height);

    m.hide();

    connect(&m, SIGNAL(resetSnap()), this, SLOT(ResetSnap()));
}

MaskWidget::~MaskWidget()
{
    delete ui;
}

void MaskWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        m_pressPos = event->pos();

        isPressed = true;
        update();
    }

    QWidget::mousePressEvent(event);
}

void MaskWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (isPressed)
    {
        isPressed = false;
        QRegion all(0, 0, width(), height());

        QRegion sub(m_maskRect);
        setMask(all.subtracted(sub));


        QPixmap combined(this->width(), this->height());
        combined.fill(Qt::transparent);
        QPainter painter(&combined);

        QList<QScreen*> screens = QGuiApplication::screens();
        for (QScreen *screen : screens)
        {
            m_image = screen->grabWindow(0);
            painter.drawPixmap(screen->geometry().x(), 0, screen->geometry().width(), screen->geometry().height(), m_image);
        }

        auto gpos = mapToGlobal(event->pos());
        auto gposStart = mapToGlobal(m_pressPos);
        qDebug()<<gpos<<gposStart;
        m_image = combined.copy(qMin(gpos.x(), gposStart.x()), qMin(gpos.y(), gposStart.y()),
                                qFabs(gpos.x() - gposStart.x()), qFabs(gpos.y() - gposStart.y()));
        this->hide();

        m.SetImage(m_image);
        update();

        m.show();

    }

    return QWidget::mouseReleaseEvent(event);
}

void MaskWidget::mouseMoveEvent(QMouseEvent* event)
{
    if (isPressed)
    {
        m_newPos = event->pos();
        QRegion all(0, 0, width(), height());
        m_maskRect = QRect(qMin(m_pressPos.x(), m_newPos.x()),
                       qMin(m_pressPos.y(), m_newPos.y()),
                       qFabs(m_newPos.x() - m_pressPos.x()),
                       qFabs(m_newPos.y() - m_pressPos.y()));

        QRegion sub(m_maskRect);
        setMask(all.subtracted(sub));
        
        update();
    }
    return QWidget::mouseMoveEvent(event);
}

void MaskWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    
    painter.setPen(Qt::red);
    painter.drawRect(m_maskRect.x()-1, m_maskRect.y()-1, m_maskRect.width()+2, m_maskRect.height() + 2);

}

void MaskWidget::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape)
    {
        close();
    }
    QWidget::keyPressEvent(event);
}

void MaskWidget::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);
}

void MaskWidget::ResetSnap()
{
    QRegion all(0, 0, width(), height());
    setMask(all);
    m_maskRect.setRect(0,0,0,0);
    this->show();
}

main.cpp

cpp 复制代码
#include "mainwindow.h"
#include "maskwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MaskWidget m;
    m.move(0, 0);
    m.show();



    return a.exec();
}

多个屏幕时,默认设置位置和大小总是在一个屏,需要用move()将它移动到(0, 0)位置。多屏幕跨屏幕截图时,先分别截取每个屏幕的图,然后把他们拼起来。

代码

相关推荐
不会写DN3 分钟前
如何让两个Go程序远程调用?
开发语言·qt·golang
A.A呐15 小时前
【QT第三章】常用控件2
开发语言·qt
笨笨马甲15 小时前
Qt 实现三维坐标系的方法
开发语言·qt
谁动了我的代码?16 小时前
VNC中使用QT的GDB调试,触发断点时与界面窗口交互导致整个VNC冻结
开发语言·qt·svn
肖恭伟16 小时前
QtCreator Linux ubuntu24.04问题集合
linux·windows·qt
vegetablesssss17 小时前
QT国际化翻译
qt
困死,根本不会17 小时前
Qt Designer 基础操作学习笔记
开发语言·笔记·qt·学习·microsoft
喜欢喝果茶.18 小时前
Qt MQTT部署
开发语言·qt
浅碎时光80718 小时前
Qt 窗口 (菜单 工具栏 状态栏 浮动窗口 对话框)
qt
GIS阵地18 小时前
一场由Qt5 painter的drawRect引起的血雨腥风
开发语言·qt·gis·qgis