Faire un screenshot en C++ avec Qt

Publié dans C / C++ | Marqué avec ,
Share

Faire un screenshot (imprim écran) en C++ à l’aide du framework Qt est étonnamment trivial. Il est très facile de « prendre en photo » tout votre écran, ou seulement une fenêtre (en connaissant son Window Id) à l’aide de la méthode grabWindow de la classe QPixmap. Un petit exemple simple pour l’écran entier (Window Id : QApplication::desktop()->winId()) que l’on enregistre dans le dossier courant en PNG.

// - Shoot the screen
QPixmap pixmap = QPixmap();
pixmap = QPixmap::grabWindow(QApplication::desktop()->winId());

// - Save this picture
QString format = "png";
QString filePath = QDir::currentPath()+"/myscreen."+format;
pixmap.save(filePath, format.toAscii());

Classe d’instrumentation

Ce qui m’intéresse aujourd’hui, c’est de créer une classe d’instrumentation me permettant de prendre un imprim ecran de l’application Qt courante. Rien de plus simple puisque les QWidget utilisés dans Qt pour la GUI ont tous une méthode winId() permettant de retrouver leur Window Id.

#ifndef SCREENSHOTMANAGER_H
#define SCREENSHOTMANAGER_H

#include <QPixmap>
#include <QApplication>
#include <QDesktopWidget>
#include <QWidget>
#include <QDir>

class ScreenshotManager
{
public:
    ScreenshotManager(QString folder="", QString fileName="", bool enableCounter=true);
    /**
      * Shoot the destktop window
      */
    void saveScreen(QString prefixe="");
    /**
      * Shoot a peculiar window  , and save it as a PNG file
      * in <current path>/<folder>/<prefixe><filename><shot number>.png
      * @param winId Window Id of the window to shoot @see{QWidget::winId()}
      * @param prefixe File name prefixe of the file to save (empty by default)
      */
    void saveScreen(WId winId, QString prefixe="");

    void setFolder(QString folder);
    void setFileName(QString fileName);
    void setEnableCounter(bool enableCounter);
    void setShotCounter(int shotCounter=0);

private:
    Logger log;
    int shotCounter;
    QString folder;
    QString fileName;
    bool enableCounter;
};
#endif // SCREENSHOTMANAGER_H
#include "ScreenshotManager.h"

ScreenshotManager::ScreenshotManager(QString folder, QString fileName, bool enableCounter)
{
    setShotCounter();
    setFolder(folder);
    setFileName(fileName);
    setEnableCounter(enableCounter);
}


void ScreenshotManager::saveScreen(QString prefixe)
{
    saveScreen(QApplication::desktop()->winId(), prefixe);
}

void ScreenshotManager::saveScreen(WId winId, QString prefixe)
{
    // - Shoot the screen
    QPixmap pixmap= QPixmap();
    pixmap= QPixmap::grabWindow(winId);

    // - Save this picture
    QString format = "png";
    shotCounter++;
    QString fileName = prefixe+this->fileName+(enableCounter ? QString::number(shotCounter) : "")+"."+format;
    QString filePath = QDir::currentPath()+"/"+this->folder+fileName;
    pixmap.save(filePath, format.toAscii());
}


void ScreenshotManager::setFolder(QString folder)
{
    this->folder = folder+("" != folder && !folder.endsWith("/") ? "/" : "");
    // - Check if folder exists
    if ("" != folder && !QDir(folder).exists()) {
        QDir().mkpath(folder);
    }
}

void ScreenshotManager::setFileName(QString fileName)
{
    this->fileName = fileName;
}

void ScreenshotManager::setEnableCounter(bool enableCounter)
{
    this->enableCounter = enableCounter;
}

void ScreenshotManager::setShotCounter(int shotCounter)
{
    this->shotCounter = shotCounter;
}

Cette petite classe s’utilise alors très simplement.

#include "ScreenshotManager.h"

int main(int argc, char *argv[])
{
    ScreenshotManager shootManager = ScreenshotManager("myScreenshots", "screenshot");
    shootManager.saveScreen(/*winId*/);
    return 0;
}

A retenir

  • Prendre un imprim ecran: QPixmap::grabWindow(winId)
    • Window Id d’un QWidget : QWidget::winId()
    • Window Id de l’écran entier : QApplication::desktop()->winId()
  • Enregistrer le résultat : QPixmap::save(filepath, format)

Pour aller plus loin

Ma classe d’instrumentation ne permet pas de sélectionner où enregistrer l’image de l’imprim ecran, mais ce n’était pas mon but. Un très bon tutoriel Qt avec code à la clé explique comment créer une petite GUI pour prendre des screenshots, avec retardateur, et enregistre le résultat dans le fichier de son choix : Qt Screenshot Example.

One Response to Faire un screenshot en C++ avec Qt

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *