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()
- Window Id d’un QWidget :
- 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