gpt4 book ai didi

qt - 捕获QML绘图缓冲区,而不显示

转载 作者:行者123 更新时间:2023-12-04 11:08:26 27 4
gpt4 key购买 nike

我需要抓取每个QML(QtQuick 2)图纸框架并通过网络发送。
目前,我已经使用了下面列出的方法,但是这种方法有两个很大的缺点

1)由于存在Qt5文档,grabWindow()函数存在性能问题

2)它不能与隐藏的QML窗口一起使用

是否可以在QQuickWindow::afterRendering之后获得OpenGL渲染缓冲区?
使用FBO?共享的OpenGL上下文?

class Grab: public QObject
{
public:
Grab( QQuickWindow * wnd ) : wnd_(wnd) {}

public slots:

void Grabme()
{
QImage image = wnd_->grabWindow();
}

private:

QQuickWindow *wnd_;
};

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);


QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/grab1/main.qml"));
viewer.showExpanded();

Grab grab( &viewer );
QObject::connect( &viewer, &QtQuick2ApplicationViewer::frameSwapped,
&grab, &Grab::Grabme, Qt::DirectConnection );


return app.exec();
}

最佳答案

下面的示例可以将任何qml内容捕获到FBO,然后通过信号将其作为Image发送。
这种方法的唯一问题是可见性,必须成功看到抓取窗口。如果有人知道如何防止这种情况,您可以帮助我并提供更高级的方法。

// main.cpp
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

GrabWindow grab;
grab.setResizeMode( QQuickView::SizeViewToRootObject );
grab.setSource( QUrl::fromLocalFile("qml/main.qml") );
grab.setFlags( Qt::Popup );

grab.show();
return app.exec();
}


// grabwindow.hpp
#pragma once
#include <QOpenGLFramebufferObject>
#include <QScopedPointer>
#include <QQuickView>
#include <QImage>

class GrabWindow: public QQuickView
{
Q_OBJECT

signals:
void changeImage( const QImage &image );

public:
GrabWindow( QWindow * parent = 0 );

private slots:
void afterRendering();
void beforeRendering();

private:
QScopedPointer<QOpenGLFramebufferObject> fbo_;
};

// grabwindow.cpp
#include "grabwindow.hpp"
#include <limits>

GrabWindow::GrabWindow( QWindow * parent ) :
QQuickView( parent )
{
setClearBeforeRendering( false );
setPosition( std::numeric_limits<unsigned short>::max(), std::numeric_limits<unsigned short>::max() );

connect( this, SIGNAL( afterRendering() ), SLOT( afterRendering() ), Qt::DirectConnection );
connect( this, SIGNAL( beforeRendering() ), SLOT( beforeRendering() ), Qt::DirectConnection );
}

void GrabWindow::afterRendering()
{
if( !fbo_.isNull() )
{
emit changeImage( fbo_->toImage() );
}
}

void GrabWindow::beforeRendering()
{
if (!fbo_)
{
fbo_.reset(new QOpenGLFramebufferObject( size(), QOpenGLFramebufferObject::NoAttachment) );
setRenderTarget(fbo_.data());
}
}

关于qt - 捕获QML绘图缓冲区,而不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17146747/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com