如何在各种显示器上使用 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,但这很简单。
我是 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,但这很简单。