Qt 5.6 | Qt Widgets | Screenshot Example | screenshot.cpp Example File

Qt 5.6.2 Reference Documentation

# screenshot.cpp Example File

desktop/screenshot/screenshot.cpp

      /****************************************************************************
      **
      ** Copyright (C) 2015 The Qt Company Ltd.
      ** Contact: http://www.qt.io/licensing/
      **
      ** This file is part of the examples of the Qt Toolkit.
      **
      ** $QT_BEGIN_LICENSE:BSD$
      ** You may use this file under the terms of the BSD license as follows:
      **
      ** "Redistribution and use in source and binary forms, with or without
      ** modification, are permitted provided that the following conditions are
      ** met:
      **   * Redistributions of source code must retain the above copyright
      **     notice, this list of conditions and the following disclaimer.
      **   * Redistributions in binary form must reproduce the above copyright
      **     notice, this list of conditions and the following disclaimer in
      **     the documentation and/or other materials provided with the
      **     distribution.
      **   * Neither the name of The Qt Company Ltd nor the names of its
      **     contributors may be used to endorse or promote products derived
      **     from this software without specific prior written permission.
      **
      **
      ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
      **
      ** $QT_END_LICENSE$
      **
      ****************************************************************************/

      #include <QtWidgets>

      #include "screenshot.h"

      Screenshot::Screenshot()
          :  screenshotLabel(new QLabel(this))
      {
          screenshotLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
          screenshotLabel->setAlignment(Qt::AlignCenter);

          const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
          screenshotLabel->setMinimumSize(screenGeometry.width() / 8, screenGeometry.height() / 8);

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

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

          typedef void (QSpinBox::*QSpinBoxIntSignal)(int);
          connect(delaySpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged),
                  this, &Screenshot::updateCheckBox);

          hideThisWindowCheckBox = new QCheckBox(tr("Hide This Window"), optionsGroupBox);

          QGridLayout *optionsGroupBoxLayout = new QGridLayout(optionsGroupBox);
          optionsGroupBoxLayout->addWidget(new QLabel(tr("Screenshot Delay:"), 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(tr("New Screenshot"), this);
          connect(newScreenshotButton, &QPushButton::clicked, this, &Screenshot::newScreenshot);
          buttonsLayout->addWidget(newScreenshotButton);
          QPushButton *saveScreenshotButton = new QPushButton(tr("Save Screenshot"), this);
          connect(saveScreenshotButton, &QPushButton::clicked, this, &Screenshot::saveScreenshot);
          buttonsLayout->addWidget(saveScreenshotButton);
          QPushButton *quitScreenshotButton = new QPushButton(tr("Quit"), 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(tr("Screenshot"));
          resize(300, 200);
      }

      void Screenshot::resizeEvent(QResizeEvent * /* event */)
      {
          QSize scaledSize = originalPixmap.size();
          scaledSize.scale(screenshotLabel->size(), Qt::KeepAspectRatio);
          if (!screenshotLabel->pixmap() || scaledSize != screenshotLabel->pixmap()->size())
              updateScreenshotLabel();
      }

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

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

      void Screenshot::saveScreenshot()
      {
          const QString format = "png";
          QString initialPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
          if (initialPath.isEmpty())
              initialPath = QDir::currentPath();
          initialPath += tr("/untitled.") + format;

          QFileDialog fileDialog(this, tr("Save As"), initialPath);
          fileDialog.setAcceptMode(QFileDialog::AcceptSave);
          fileDialog.setFileMode(QFileDialog::AnyFile);
          fileDialog.setDirectory(initialPath);
          QStringList mimeTypes;
          foreach (const QByteArray &bf, QImageWriter::supportedMimeTypes())
              mimeTypes.append(QLatin1String(bf));
          fileDialog.setMimeTypeFilters(mimeTypes);
          fileDialog.selectMimeTypeFilter("image/" + format);
          fileDialog.setDefaultSuffix(format);
          if (fileDialog.exec() != QDialog::Accepted)
              return;
          const QString fileName = fileDialog.selectedFiles().first();
          if (!originalPixmap.save(fileName)) {
              QMessageBox::warning(this, tr("Save Error"), tr("The image could not be saved to \"%1\".")
                                   .arg(QDir::toNativeSeparators(fileName)));
          }
      }

      void Screenshot::shootScreen()
      {
          QScreen *screen = QGuiApplication::primaryScreen();
          if (const QWindow *window = windowHandle())
              screen = window->screen();
          if (!screen)
              return;

          if (delaySpinBox->value() != 0)
              QApplication::beep();

          originalPixmap = screen->grabWindow(0);
          updateScreenshotLabel();

          newScreenshotButton->setDisabled(false);
          if (hideThisWindowCheckBox->isChecked())
              show();
      }

      void Screenshot::updateCheckBox()
      {
          if (delaySpinBox->value() == 0) {
              hideThisWindowCheckBox->setDisabled(true);
              hideThisWindowCheckBox->setChecked(false);
          } else {
              hideThisWindowCheckBox->setDisabled(false);
          }
      }

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