在linux不带X window的系统中运行Qt程序,无法使用一般的截图程序。
Qt5使用EGLFS作为控件渲染,抛弃了传统的LInuxFd,因此采用读取“/dev/df0"的做法无法读取到正确的屏幕图像。所以必须通过Qt的控件截图。
提供两种方法:
(1)截图某个控件
(2)截图整个窗口
直接上代码:
.h 文件
#include <QDebug>
#include <QImage>
#include <QSharedPointer>
#include <QQuickItem>
#include <QQuickItemGrabResult>
#include <QQuickWindow>
class ScreenShot : public QObject
{
Q_OBJECT
public:
explicit ScreenShot(QObject *parent = nullptr);
Q_INVOKABLE void shootScreen(QObject *itemObj); //截图控件
Q_INVOKABLE void shootScreenWindow(QQuickWindow *rootWindow); //截图窗口
private slots:
void saveimage();
private:
QQuickItem *grabItem;
QSharedPointer<QQuickItemGrabResult> grabResult;
};
.cpp文件
#include <QDateTime>
ScreenShot::ScreenShot(QObject *parent) : QObject(parent)
{
}
void ScreenShot::shootScreen(QObject *itemObj)
{
grabItem = qobject_cast<QQuickItem*>(itemObj);
grabResult = grabItem->grabToImage();
QQuickItemGrabResult * grabResultData = grabResult.data();
connect(grabResultData,SIGNAL(ready()),this,SLOT(saveimage()));
}
void ScreenShot::shootScreenWindow(QQuickWindow *rootWindow)
{
QImage image = rootWindow->grabWindow();
QString filePathName = "/myPath/";
filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");
filePathName += QString(".jpg");
image.save(filePathName,"JPG");
}
void ScreenShot::saveimage()
{
QString filePathName = "/myPath/";
filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");
filePathName += QString(".jpg");
QImage img = grabResult->image();
if(img.save(filePathName)){
qDebug("save sucessfully!");
}
}
将ScreenShot的实例注册到qml中,可以在qml中直接调用,一般在main函数中注册:
main.cpp
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QQmlApplicationEngine engine;
ScreenShot screenshot;
engine.rootContext()->setContextProperty("screenshot", &screenshot);
...
return app.exec();
}
.qml
ApplicationWindow {
id:rootWindow
visible: true
Button{
id: button
width: 1280
height: 800
onClicked:
{
screenshot.shootScreen(button)
screenshot.shootScreenWindow(rootWindow)
}
}
...
}