QQuickWidget захватить изображение
Я сохраняю изображение QQuickWidget
с несколькими детьми QML, но все, что у меня есть, это пустое изображение.
Сторона C++:
QQuickWidget* content..
content->setSource(QUrl("qml:/main.qml"));
QPixmap *pm = content->grab(QRect(QPoint(0,0),QSize(-1,-1));
pm->save("someFilename.png", 0, 100);
Сторона QML:
Rectangle{ width: 5; height: 5; color: "yellow"; objectname: "rootobj"}
В QML я хочу динамически добавлять детей и иметь возможность показывать их на изображении. я пытался QQuickWindow
grabWindow
метод с подключением к слоту, и он работает, но он захватывает только видимую область окна, и мне нужно захватить весь QML.
Я считаю, что это не ракетостроение, просто я чего-то не получу. Спасибо за ваши ответы!
Приложение:
Хорошо, я не думаю, что это проблема до / после рендеринга, так как я вижу все дочерние элементы qml до того, как я вызову средство захвата изображений. Так что извините за не быть точным.
сторона C++:
QQuickWidget* content..
content->setSource(QUrl("qml:/main.qml"));
//do all my dynamic qml children adding
После того как я смогу визуально увидеть весь мой qml:
QPixmap *pm = content->grab(QRect(QPoint(0,0),QSize(-1,-1));
pm->save(....
Если я не ошибаюсь, я не думаю, что это проблема рендеринга. Спасибо!
2 ответа
Проблема, как сказал Мидо. Вы можете решить это следующим образом.
Создать класс Viewer
:
viewer.h
class Viewer : public QQuickView{
Q_OBJECT
public:
explicit Viewer(QWindow *parent = 0);
Viewer(bool showBar);
virtual ~Viewer();
void setMainQmlFile(const QString file);
void addImportPath(const QString path);
public slots:
void beforeRendering();
void afterRendering()
}
Viewer.cpp
#include "viewer.h"
Viewer::Viewer(QWindow *parent)
: QQuickView(parent)
{
setWidth(800);
setHeight(480);
connect(this, SIGNAL(beforeRendering()), this, SLOT(beforeRendering()));
connect(this, SIGNAL(afterRendering()), this, SLOT(afterRendering()));
}
void Viewer::setMainQmlFile(const QString file)
{
setSource(QUrl::fromLocalFile(file));
}
void Viewer::addImportPath(const QString path)
{
engine()->addImportPath(path);
}
void Viewer::beforeRendering()
{
//
}
void Viewer::afterRendering()
{
//grab window
QImage img = this->grabWindow();
img.save(path);
//or your code
}
main.cpp
Viewer *viewer = new Viewer;
//
///
//
viewer->setMainQmlFile(QStringLiteral("qml/main.qml"));
viewer->show();
Я думаю, что ваша проблема заключается в том, что экран захвата делается до рендеринга объекта QML. Для того, чтобы заставить его работать, вы должны подключить захват сигнала после рендеринга сигнала:
connect(this, SIGNAL(beforeRendering()), this, SLOT(sltBeforeRendering()));
connect(this, SIGNAL(afterRendering()), this, SLOT(sltAfterRendering()));
захватить sltAfterRendering
слот.
Чтобы захватить экран, я использую grabWindow()
функция, и я называю это из QML. Это зависит от поведения, которое вы хотите от вашего программного обеспечения.
Попробуй это:
grabber.h
#ifndef GRABBER_H
#define GRABBER_H
#include <QObject>
#include <QImage>
#include <QQuickView>
class Grabber : public QObject
{
Q_OBJECT
public:
explicit Grabber(QObject *parent = 0);
Grabber(QQuickView *view);
~Grabber();
Q_INVOKABLE void capture(QString const &path) const;
signals:
public slots:
private:
QQuickView* view_;
};
#endif // GRABBER_H
grabber.cpp
#include "grabber.h"
Grabber::Grabber(QObject *parent) :
QObject(parent)
{
}
Grabber::Grabber(QQuickView* view) :
view_(view)
{
}
Grabber::~Grabber()
{
if(view_ != NULL)
{
delete view_;
view_ = NULL;
}
}
void Grabber::capture(QString const &path) const
{
QImage img = view_->grabWindow();
img.save(path);
}
main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QQmlContext>
#include <QQmlEngine>
#include "grabber.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer *viewer = new QtQuick2ApplicationViewer;
Grabber * grab = new Grabber(viewer);
viewer->setHeight(480);
viewer->setWidth(800);
viewer->rootContext()->setContextProperty("grab", grab);
viewer->setMainQmlFile(QStringLiteral("qml/main.qml"));
viewer->showExpanded();
return app.exec();
}
Вызовите его из QML с помощью:
grab.capture(path + "imageName.png")