Qt截图官方demo

screen.h

#ifndef SCREEN_H
#define SCREEN_H

#include <QWidget>

class QLabel;
class QSpinBox;
class QCheckBox;
class QPushButton;

class Screen : public QWidget
{
    Q_OBJECT

public:
    Screen(QWidget *parent = nullptr);
    ~Screen();

protected:
    void resizeEvent(QResizeEvent* event) override;
    /*
    这个事件处理程序可以在子类中重新实现,以接收在event参数中传递的小部件调整大小事件。
    当调用resizeEvent()时,小部件已经有了新的几何形状。旧的size可以通过QResizeEvent::oldsizeO访问。
    在处理调整大小事件后,小部件将被擦除并接收一个paint事件。在这个处理程序中不需要(或应该)绘制任何图形。
    */

private slots:
    void newScreenshot();//准备了一个新的截图
    void saveScreenshot();//保存最后一个截图
    void shootScreen();//截屏
    void updateCheckBox();//启用或禁用隐藏此窗口选项。

private:
    void updateScreenshotLabel();

    QPixmap originalPixmap;
    QLabel* screenshotLabel;
    QSpinBox* delaySpinBox;
    QCheckBox* hideThisWindowCheckBox;
    QPushButton* newScreenshotButton;
};
#endif // SCREEN_H

screen.cpp

#include "screen.h"
#include<QLabel>
#include<QScreen>
#include<QVBoxLayout>
#include<QRect>
#include<QGroupBox>
#include<QSpinBox>
#include<QcheckBox>
#include<QGridLayout>
#include<QPushButton>
#include<QTimer>
#include<QStandardPaths>
#include<QDir>
#include<QFileDialog>
#include<QStringList>
#include<QList>
#include<QByteArray>
#include<QImageWriter>
#include<QDialog>
#include<QMessageBox>
#include<QGuiApplication>
#include<QWindow>
#include<QApplication>

Screen::Screen(QWidget* parent)
    : screenshotLabel(new QLabel(this))
{
    screenshotLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    screenshotLabel->setAlignment(Qt::AlignCenter);//设置对齐方式

    const QRect screenGeometry = screen()->geometry();
    /*
    * screen返回小部件所在的屏幕
    * 
    */

    screenshotLabel->setMinimumSize(screenGeometry.width() / 8, screenGeometry.height() / 8);

    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(screenshotLabel);

    QGroupBox* optionsGroupBox = new QGroupBox(QStringLiteral("设置"), this);
    delaySpinBox = new QSpinBox(optionsGroupBox);
    delaySpinBox->setSuffix(tr(" s"));
    delaySpinBox->setMaximum(60);

    connect(delaySpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
        this, &Screen::updateCheckBox);

    hideThisWindowCheckBox = new QCheckBox(QStringLiteral("隐藏窗口"), optionsGroupBox);

    QGridLayout* optionsGroupBoxLayout = new QGridLayout(optionsGroupBox);
    optionsGroupBoxLayout->addWidget(new QLabel(QStringLiteral("截图延迟:"),this),0,0);
    optionsGroupBoxLayout->addWidget(delaySpinBox,0,1);
    optionsGroupBoxLayout->addWidget(hideThisWindowCheckBox,1,0,1,2);
    
    mainLayout->addWidget(optionsGroupBox);

    QHBoxLayout* buttonsLayout = new QHBoxLayout;
    newScreenshotButton = new QPushButton(QStringLiteral("新截图"), this);
    connect(newScreenshotButton, &QPushButton::clicked, this, &Screen::newScreenshot);
    buttonsLayout->addWidget(newScreenshotButton);
    QPushButton* saveScreenshotButton = new QPushButton(QStringLiteral("保存截图"), this);
    connect(saveScreenshotButton, &QPushButton::clicked, this, &Screen::saveScreenshot);
    buttonsLayout->addWidget(saveScreenshotButton);
    QPushButton* quitScreenshotButton = new QPushButton(QStringLiteral("退出"), this);
    quitScreenshotButton->setShortcut(Qt::CTRL + Qt::Key_Q);
    connect(quitScreenshotButton, &QPushButton::clicked, this, &QWidget::close);
    buttonsLayout->addWidget(quitScreenshotButton);
    buttonsLayout->addStretch();
    mainLayout->addLayout(buttonsLayout);

    shootScreen();
    delaySpinBox->setValue(5);
    setWindowTitle(QStringLiteral("截屏"));
    resize(300, 200);
}

Screen::~Screen()
{
}

void Screen::resizeEvent(QResizeEvent* event)
{
    /*
    * scale()
    *这是一个重载函数。根据指定的模式,将大小缩放为具有给定大小的矩形。
    *Qt::KeepAspectRatio
    *在给定的矩形内,大小被缩放为尽可能大的矩形,保持长宽比。
    * 
    */
    QSize scaledSize = originalPixmap.size();
    scaledSize.scale(screenshotLabel->size(), Qt::KeepAspectRatio);
    if (!screenshotLabel->pixmap() || scaledSize != screenshotLabel->pixmap()->size())
        updateScreenshotLabel();
}

void Screen::newScreenshot()
{
    if (hideThisWindowCheckBox->isChecked())
        hide();
    newScreenshotButton->setDisabled(true);

    QTimer::singleShot(delaySpinBox->value() * 1000, this, &Screen::shootScreen);
    
}

void Screen::saveScreenshot()
{
    /*
    * 当用户按下Save按钮时,saveScreenshot()槽被调用,它使用QFileDialog类显示一个文件对话框。
    QFile对话框使用户能够遍历文件系统以选择一个或多个文件或目录。
    创建QFile对话框最简单的方法是使用方便的静态函数。
    这里,我们在堆栈上实例化对话框,以便能够设置支持的Qlmage Writer的mime类型,允许用户以各种格式保存。
    我们将默认文件格式定义为png,并将文件对话框的初始路径设置为从QStandardPaths获得的图片的位置,
    默认为运行应用程序的路径。我们通过调用QDialog::exec()来运行对话框,
    并在用户取消对话框时返回。如果对话框被接受,我们通过调用QFile dialog::selectedFiles()获得一个文件名。
    该文件不必存在。如果文件名有效,我们使用QPixmap::save()函数将截图的原始pixmap保存到该文件中。
    */
    const QString format = "png";       //格式
    QString initialPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
    /*返回包含用户图片或照片的目录。这是一个通用值。如果不存在特定于图片文件的目录,则返回用于存储用户文档的合理回退。*/
    if (initialPath.isEmpty())
        initialPath = QDir::currentPath();
    initialPath += tr("/unittled.") + format;
    
    QFileDialog fileDialog(this, QStringLiteral("另存为"), initialPath);
    fileDialog.setAcceptMode(QFileDialog::AcceptSave);
    /*
    * 这个属性保存对话框的接受模式操作模式定义对话框是用于打开还是保存文件。默认情况下,该属性设置为AcceptOpen。
    */
    fileDialog.setFileMode(QFileDialog::AnyFile);
    /*
    * 这个属性保存对话框的文件模式文件模式定义了用户希望在对话框中选择的项的数量和类型。
    *默认情况下,此属性设置为AnyFile。这个函数将为FileNane和Accept DialogLabels设置标签。
    *可以在调用setFileMode O之后设置自定义文本。
    */
    fileDialog.setDirectory(initialPath);
    /*设置文件对话框的当前目录。*/
    QStringList mimeTypes;
    const QList<QByteArray>baMimeTypes = QImageWriter::supportedMimeTypes();
    /*返回QImageWriter支持的MIME类型列表。*/
    for (const QByteArray& bf : baMimeTypes)
        mimeTypes.append(QLatin1String(bf));
    /*定义OT_NO_CAST_FROM_ASCII(如QString文档中解释的那样)
    的应用程序不能访问QString的const char * API。
    为了提供一种高效的指定常量Latin-1字符串的方法,
    Qt提供了QLatinlString,它只是对const char *的一个非常薄的包装。
    使用QLatinlString,上面的示例代码就变成了*/
    fileDialog.setMimeTypeFilters(mimeTypes);
    fileDialog.selectMimeTypeFilter("image/" + format);
    fileDialog.setDefaultSuffix(format);
    /*
    * 如果没有指定其他后缀,则为文件名添加后缀此属性指定一个字符串,
    *如果该字符串已经没有后缀,则将添加到该filenane。
    *后缀通常用于表示文件类型(例如:txt表示文本文件)。
    *如果第一个字符是点('.'),它将被删除。
    */
    if (fileDialog.exec() != QDialog::Accepted)
        return;
    const QString fileName = fileDialog.selectedFiles().first();
    /*返回字符串列表,其中包含对话框中所选文件的绝对路径。
    如果没有选择文件,或者模式不是ExistingFiles或ExistingFile, 
    selectedFiles O包含视口中的当前路径。*/
    if (!originalPixmap.save(fileName)) {
        QMessageBox::warning(this, QStringLiteral("保存失败"), tr("The image could not be saved to \"%1\".")
            .arg(QDir::toNativeSeparators(fileName)));
    }
}

void Screen::shootScreen()
{
    /*
    调用shootScreen()槽来获取屏幕截图。
    首先,我们通过检索QWindow及其QScreen找到窗口所在的QScreen实例,默认为主屏幕。
    如果找不到屏幕,则返回。
    虽然这种情况不太可能发生,但应用程序应该检查空指针,因为可能存在没有连接屏幕的情况。
    •如果用户选择延迟截图,我们使用静态QApplication::beep()函数使应用程序在截图时发出哔哔声。
    然后使用QScreen.grabWindow()函数获取屏幕截图。
    该函数获取作为参数传递的窗口内容,从中生成像素图并返回该像素图。
    窗口id可以通过QWidget:winld()或QWindow::winld()获取。
    然而,在这里,我们只是传递O作为窗口id,表明我们想要获取整个屏幕。
    我们使用私有的updateScreenshotLabel()函数来更新截图预览标签。
    然后启用New截屏按钮,最后,如果截屏窗口小部件在截屏时是隐藏的,则该窗口小部件可见。
    */
    QScreen* screen = QGuiApplication::primaryScreen();
    /*此属性保存应用程序的主(或默认)屏幕。
    除非另有说明,否则这将是QWindows最初显示的屏幕。
    prinaryScreenChanged信号是在Qt 5.6中引入的。*/
    if (const QWindow* window = windowHandle())
        screen = window->screen();
    if (!screen)
        return;
    if (delaySpinBox->value() != 0)
        QApplication::beep();

    originalPixmap = screen->grabWindow(0);
    /*
    创建并返回由QRect (x, y, width, height)限制的给定窗口的内容构建的像素图。
    参数(x, y)指定窗口中的偏移量,而(width, height)指定要复制的区域。
    如果width为负,则该函数将所有内容复制到窗口的右边框。
    如果height为负,该函数将所有内容复制到窗口底部。
    offset和size参数以与设备无关的像素指定。
    当从高dpi屏幕抓取时,返回的像素图可能比请求的大小更大。
    调用QPixmap:: devicePixelRatioO来确定是否存在这种情况。
    可以使用QWidget::winIdO函数检索窗口系统标识符(wId)。
    使用窗口标识符而不是Qwidget的基本原理是支持抓取不属于应用程序的窗口、窗口系统框架等。*/
    updateScreenshotLabel();

    newScreenshotButton->setDisabled(false);

    if (hideThisWindowCheckBox->isChecked())
        show();
}

void Screen::updateCheckBox()
{
    /*
    隐藏此窗口选项的启用或禁用取决于屏幕截图的延迟。
    如果没有延迟,应用程序窗口不能被隐藏,并且该选项的复选框被禁用。
    每当用户使用截图延迟选项更改延迟时,就会调用updatecheckBox()插槽。*/
    if (delaySpinBox->value() == 0) {
        hideThisWindowCheckBox->setDisabled(true);
        hideThisWindowCheckBox->setChecked(false);
    }
    else {
        hideThisWindowCheckBox->setDisabled(false);
    }

}

void Screen::updateScreenshotLabel()
{
    screenshotLabel->setPixmap(originalPixmap.scaled(screenshotLabel->size(),
        Qt::KeepAspectRatio,
        Qt::SmoothTransformation));
}

main.cpp

#include "screen.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Screen w;
    w.show();
    return a.exec();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: “qt canpool fancy demo”在中文中意思是“使用Qt可以创建华丽的演示”。Qt是一个开源的跨平台应用程序开发框架,它提供了丰富的形界面和功能库,可用于创建各种类型的应用程序,包括演示。 Qt Canpool Fancy Demo为开发者提供了一个用于展示Qt框架强大功能的例子。通过使用Qt形界面系统和形渲染引擎,开发者可以创建出华丽的、吸引人的演示。这些演示可以包含各种特效、动画、渐变和其他视觉元素,以展示Qt的灵活性和多样性。 Qt Canpool Fancy Demo还可以展示Qt的多平台兼容性。Qt可以在多种操作系统上运行,包括Windows、macOS、Linux等等。这意味着您可以使用Qt来创建适用于不同平台的演示,以满足不同用户的需求。 此外,Qt Canpool Fancy Demo还可以展示Qt形用户界面设计器的优势。Qt提供了一个可视化界面设计器,使开发者能够通过简单拖拽组件的方式进行界面设计。这个设计工具非常强大且易于使用,使得开发者可以在短时间内创建出华丽的演示。 总的来说,Qt Canpool Fancy Demo展示了Qt框架作为一个功能强大的应用程序开发工具的能力。无论是在形界面设计、特效展示还是多平台兼容性方面,Qt都可以帮助开发者创建出华丽而且功能丰富的演示。 ### 回答2: Qt Canpool Fancy Demo是一个使用Qt框架开发的漂亮的演示程序。 该演示程序使用了Qt形界面和动画特效功能,展示了一些引人注目的特性。它有一个精致的用户界面,设计简洁而美观。用户可以通过演示程序中的按钮和菜单来进行各种操作。 Qt Canpool Fancy Demo演示了一些高级的形特效,如淡入淡出、旋转和缩放。用户可以通过控制面板来调整这些特效的参数,使得演示效果更加个性化。同时,程序还展示了一些形控件的使用方法,如按钮、滑动条和进度条等。 除了形特效,Qt Canpool Fancy Demo还提供了一些实用的功能。例如,用户可以通过程序中的文件浏览器来选择和编辑文件,还可以通过网络浏览器来访问网站。这些功能增加了应用程序的实用性和趣味性。 通过Qt的跨平台特性,Qt Canpool Fancy Demo可以运行在多种操作系统上,如Windows、MacOS和Linux等。这使得用户可以在不同的设备上获得相同的优秀使用体验。 总体而言,Qt Canpool Fancy Demo是一个用Qt开发的令人赏心悦目的演示程序,融合了形特效、实用功能和跨平台优势。无论是作为学习Qt开发的入门示例,还是用作参考和灵感的源泉,该演示程序都能够为用户带来很多乐趣和启发。 ### 回答3: Qt Canpool Fancy Demo是一个使用Qt框架编写的演示程序。这个演示程序采用了qtcanpool库来实现多线程并行计算的功能。 在这个演示中,通过多线程计算和并行处理,可以提高程序的计算效率和响应速度。当程序运行时,它会将计算任务分配给多个线程,每个线程会同时执行一部分任务,然后将结果汇总。 Qt Canpool Fancy Demo的界面设计精美,采用了Qt形界面库来创建演示程序的用户界面。用户可以通过演示程序的界面来输入计算任务的参数和数据,然后点击开始按钮来启动计算过程。 在计算过程中,演示程序会动态显示计算进度和计算结果。通过多线程并行计算,程序可以更快地完成计算任务,并将计算结果显示给用户。 此外,Qt Canpool Fancy Demo还提供了一些额外的功能,例如任务管理、线程调度和错误处理等。这些功能使得程序更加健壮和高效,用户可以更轻松地使用和控制程序的运行。 总之,Qt Canpool Fancy Demo是一个使用Qt框架开发的演示程序,通过多线程并行计算来提高计算效率和响应速度。它具有精美的界面设计和丰富的功能,非常适合用于演示和教学等用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值