如何在各种显示器上使用 Qt/C++ 获取打印屏幕?

How can I take a print screen using Qt / C++ with various monitors?

我是 Qt Creator 的新手,但我正在尝试创建和应用而不是每分钟拍摄一次屏幕截图,我在 Qt Creator 中找到了一个代码来执行此操作,但它只适用于一台显示器,如果我有两个或更多它只需要一个显示器的屏幕截图。

这是我正在使用的代码。

这是 screenshot.h

#ifndef SCREENSHOT_H
#define SCREENSHOT_H

#include <QPixmap> 
#include <QWidget>

class QCheckBox;
class QGridLayout;
class QGroupBox;
class QHBoxLayout;
class QLabel;
class QPushButton;
class QSpinBox;
class QVBoxLayout;

class screenshot : public QWidget
{
    Q_OBJECT

public:
    screenshot();

protected:
   void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;

private slots:
   void newScreenshot();
   void saveScreenshot();
   void shootScreen();
   void updateCheckBox();

private:
   void createOptionsGroupBox();
   void createButtonsLayout();
   QPushButton *createButton(const QString &text, QWidget *receiver, const char *member);
   void updateScreenshotLabel();

   QPixmap originalPixmap;

   QLabel *screenshotLabel;
   QGroupBox *optionsGroupBox;
   QSpinBox *delaySpinBox;
   QLabel *delaySpinBoxLabel;
   QCheckBox *hideThisWindowCheckBox;
   QPushButton *newScreenshotButton;
   QPushButton *saveScreenshotButton;
   QPushButton *quitScreenshotButton;

   QVBoxLayout *mainLayout;
   QGridLayout *optionsGroupBoxLayout;
   QHBoxLayout *buttonsLayout;
};

#endif // SCREENSHOT_H

这是 screenshot.cpp

#include <QtWidgets>

#include "screenshot.h"

screenshot::screenshot()
{
    screenshotLabel = new QLabel;
    screenshotLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    screenshotLabel->setAlignment(Qt::AlignCenter);
    screenshotLabel->setMinimumSize(240, 160);

    createOptionsGroupBox();
    createButtonsLayout();

    mainLayout = new QVBoxLayout;
    mainLayout->addWidget(screenshotLabel);
    mainLayout->addWidget(optionsGroupBox);
    mainLayout->addLayout(buttonsLayout);
    setLayout(mainLayout);

    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, SLOT(shootScreen()));
 }

 void screenshot::saveScreenshot()
 {
     QString format = "jpg";
     QString initialPath = QDir::currentPath() + tr("/untitled.") + format;

     QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), initialPath,
                                                tr("%1 Files (*.%2);;All Files (*)")
                                                .arg(format.toUpper())
                                                .arg(format));
   if (!fileName.isEmpty())
       originalPixmap.save(fileName, format.toLatin1().constData());
}

void screenshot::shootScreen()
{
    if (delaySpinBox->value() != 0)
       qApp->beep();
    originalPixmap = QPixmap(); // clear image for low memory situations
                            // on embedded devices.
   QScreen *screen = QGuiApplication::primaryScreen();
   if (screen)
      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::createOptionsGroupBox()
{
    optionsGroupBox = new QGroupBox(tr("Options"));

    delaySpinBox = new QSpinBox;
    delaySpinBox->setSuffix(tr(" s"));
    delaySpinBox->setMaximum(60);
    connect(delaySpinBox,SIGNAL(valueChanged(int)), this, SLOT(updateCheckBox()));
    //connect(delaySpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateCheckBox()));

    delaySpinBoxLabel = new QLabel(tr("Screenshot Delay:"));

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

    optionsGroupBoxLayout = new QGridLayout;
    optionsGroupBoxLayout->addWidget(delaySpinBoxLabel, 0, 0);
    optionsGroupBoxLayout->addWidget(delaySpinBox, 0, 1);
    optionsGroupBoxLayout->addWidget(hideThisWindowCheckBox, 1, 0, 1, 2);
    optionsGroupBox->setLayout(optionsGroupBoxLayout);
}

void screenshot::createButtonsLayout()
{
    newScreenshotButton = createButton(tr("New Screenshot"), this, SLOT(newScreenshot()));
   saveScreenshotButton = createButton(tr("Save Screenshot"), this, SLOT(saveScreenshot()));
   quitScreenshotButton = createButton(tr("Quit"), this, SLOT(close()));

   buttonsLayout = new QHBoxLayout;
   buttonsLayout->addStretch();
   buttonsLayout->addWidget(newScreenshotButton);
   buttonsLayout->addWidget(saveScreenshotButton);
   buttonsLayout->addWidget(quitScreenshotButton);
}

   QPushButton *screenshot::createButton(const QString &text, QWidget *receiver,
                                  const char *member)
{
    QPushButton *button = new QPushButton(text);
    button->connect(button, SIGNAL(clicked()), receiver, member);
    return button;
}

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

有人可以帮我修改这段代码或者告诉我该怎么做吗??

谢谢

QGuiApplication class has a screens() 方法 returns 指向计算机所有 QScreen 对象的指针列表。所以你想使用它,例如替换此代码:

QScreen *screen = QGuiApplication::primaryScreen();
if (screen)
   originalPixmap = screen->grabWindow(0);

还有更像这样的东西:

QList<QScreen *> screens = QGuiApplication::screens();
QList<QPixmap> pixmapsList;
for (int i=0; i<screens.size(); i++)
{
   const QRect r = screens[i]->geometry();
   pixmapsList.push_back(screens[i]->grabWindow(0), r.x(), r.y(), r.width(), r.height());
}

...那么当然你需要修改文件保存代码以将每个QPixmap保存在pixmapsList中,而不是只保存一个QPixmap,但这很简单。