2

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 全体をキャプチャする必要があります。

私は、これはロケット科学ではないと信じています。返信ありがとうございます。

補遺:

OK、画像グラバーを呼び出す前にすべての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(....

私が間違っていない限り、レンダリングの問題はないと思います。ありがとうございました!

4

2 に答える 2

3

問題は御堂さんの言うとおりです。以下のようにすれば解決できます。

クラスを作成します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();
于 2015-07-14T15:52:45.450 に答える
0

あなたの問題は、QML オブジェクトのレンダリングの前にキャプチャ画面が行われることだと思います。機能させるには、信号をレンダリングした後に信号のグラブを接続する必要があります。

 connect(this, SIGNAL(beforeRendering()), this, SLOT(sltBeforeRendering()));
 connect(this, SIGNAL(afterRendering()), this, SLOT(sltAfterRendering()));

sltAfterRenderingスロットでグラブを行います。

画面を取得するには、grabWindow()関数を使用し、QML から呼び出します。それは、ソフトウェアに求める動作によって異なります。

これを試して:

グラバー.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

グラバー.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")
于 2015-07-14T10:53:40.213 に答える