2016-10-14 9 views
1

私はQML UIの使用に興味があるプロジェクトをいくつか持っています。 しかし、私たちがstandart Qtレンダリングシステムを使うだけでは不十分です。QCoreApplication :: processEvents()だけでなく、すべてのUI要素をすべてのフレームに再描画しようとする必要があります。カスタムグラフィックスエンジンを使用してQt QWidgetsとQMLを作成できますか?

これは、UIのバックグラウンドでDirectXをレンダリングするためです。

この場合、ウィジェットはQWidget :: render()関数のみを使用してレンダリングする方法を見つけましたが、この方法ではGPUの代わりにCPUを使用するため、速度が遅すぎ、まったく修正できません。

だから、私が持っているもの:

  1. 私ははQApplicationは自分のアプリケーションのループに統合できます。 信号/スロットシステムは正常に動作し、プロセスイベントは右 と呼ばれます。
  2. 他のレンダリングに使用するDirectX11のレンダリングシステム グラフィック。

DirectXを使用したり、レンダリングのすべてのフレームを使用してすべてのフレームを再描画(更新)する必要があります。

既に存在するコード例: この例では、再実装されたウィジェットは、アプリケーションのメインウィンドウであり、DirectXレンダリングのコンテキストと同様に使用されます。

#ifndef _QTD3DCONTEXTWIDGET_ 
#define _QTD3DCONTEXTWIDGET_ 

#include <QtWidgets/QWidget> 
#include <QtQuick/QQuickView> 
#include <QtQuickWidgets/QQuickWidget> 
#include <QtQml/qqml.h> 
#include <QtWidgets/QPushButton> 

#include <QtGui/QPaintEngine> 
#include <QtGui/QPaintDevice> 

class QtGfxPaintEngine : public QPaintEngine 
{ 
public: 
    QtGfxPaintEngine(PaintEngineFeatures caps = PaintEngineFeatures()); 

    virtual bool begin(QPaintDevice *pdev); 
    virtual bool end(); 
    //virtual void drawEllipse(const QRectF &rect); 
    //virtual void drawEllipse(const QRect &rect); 
    virtual void drawImage(const QRectF &rectangle, 
     const QImage &image, 
     const QRectF &sr, 
     Qt::ImageConversionFlags flags = Qt::AutoColor); 

    virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); 
    virtual void drawPoints(const QPointF *points, int pointCount); 
    virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); 
    virtual void drawRects(const QRectF *rects, int rectCount); 
    virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); 
    virtual void drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p); 
    // default implementation used 
    //virtual void drawLines(const QLineF *lines, int lineCount); //not 
    //virtual void drawLines(const QLine *lines, int lineCount); 
    //virtual void drawPath(const QPainterPath &path); 
    //virtual void drawPoints(const QPoint *points, int pointCount); 
    //virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); 
    //virtual void drawRects(const QRect *rects, int rectCount); 

    virtual Type type() const; 
    virtual void updateState(const QPaintEngineState &newState); 
private: 
    int getClosestPowOfTwo(QSize& size); 
}; 

class QtD3DContextWidget : public QWidget 
{ 
    Q_OBJECT 
public: 
    QtD3DContextWidget(QWidget* parent = nullptr); 
    virtual ~QtD3DContextWidget() = default; 
    virtual QPaintEngine* paintEngine() const; 


    virtual void paintEvent(QPaintEvent* event); 

    void mousePressEvent(QMouseEvent *event) override; 

    QQuickWidget* containerWidget; 
    QPushButton* widg; 
    QtGfxPaintEngine* mPaintEngine; 
private: 

}; 

#endif // !_QTD3DCONTEXTWIDGET_ 

CPP、描画機能のない(彼らはDirectXので実装し、正常に動作している):

QtD3DContextWidget::QtD3DContextWidget(QWidget* parent /*= nullptr*/) 
    : QWidget(parent, Qt::MSWindowsOwnDC) 
{ 
    mPaintEngine = new QtGfxPaintEngine(QPaintEngine::AllFeatures); 

    QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); 
    setAttribute(Qt::WA_NativeWindow, true); 
    setAttribute(Qt::WA_TranslucentBackground, true); 
    setAttribute(Qt::WA_UpdatesDisabled, true); 
    setAttribute(Qt::WA_TransparentForMouseEvents); 
    setAttribute(Qt::WA_NoSystemBackground, true); 
    setAttribute(Qt::WA_OpaquePaintEvent, true); 

    containerWidget = new QQuickWidget(this); 
    containerWidget->setAttribute(Qt::WA_TranslucentBackground, true); 
    containerWidget->setAttribute(Qt::WA_OpaquePaintEvent, true); 
    containerWidget->setAttribute(Qt::WA_NoSystemBackground, true); 
    containerWidget->setClearColor(Qt::transparent); 

    QString sourceUi = QCoreApplication::applicationDirPath() + "/qtui/test.qml"; 
    containerWidget->setSource(QUrl::fromLocalFile(sourceUi)); 
    containerWidget->move(0, 0); 

    resize(1280, 720); 

    widg = new QPushButton("test", this); 
    //widg->setBackgroundRole(QPalette::WindowText); 
    widg->resize(50, 50); 
    widg->move(600, 300); 
    widg->show(); 
    show(); 
    setVisible(true); 
    //wrapper->show(); 

} 

QPaintEngine* QtD3DContextWidget::paintEngine() const 
{ 
    return mPaintEngine; 
} 

void QtD3DContextWidget::paintEvent(QPaintEvent* event) 
{ 

} 


QtGfxPaintEngine::QtGfxPaintEngine(PaintEngineFeatures caps /*= PaintEngineFeatures()*/) 
    : QPaintEngine(caps) 
{} 

QPaintEngine::Type QtGfxPaintEngine::type() const 
{ 
    return QPaintEngine::Direct3D; 
} 

void QtGfxPaintEngine::updateState(const QPaintEngineState &newState) 
{} 

とUI方法レンダリング中:

QPainter painter(w); 
painter.setBrushOrigin(w->containerWidget->pos()); 
w->containerWidget->render(&painter);// , w->widg->pos());// , w->widg->rect());// , QWidget::DrawChildren); 
painter.end(); 

だヘッダ

正常に動作しますが、CPUを使用します。私はそれはとても全体のウィジェットが、再描画ではなく、すべてのフレーム、そしてこの場合にはUIが「点滅」され、それが背景のような透明ではありませんrepainしようとするウィジェットです

w->repaint(); 

に置き換えることですしようと何

しかし白色である。

それとも

w->containerWidget->repaint(); 

と交換し、何もhappendsではありません。

私が見ることができるように、w-> repaint()の直後にQApplication :: processイベントを呼び出そうとしません。

私はcomAを持っています。setAttribute(Qt :: WA_UpdatesDisabled、true);私がこの方法でウィジェットをリフレッシュしようとすると。

PS:私の英語のため申し訳ありません)))

答えて

0

あなたは中央のレンダラを介してすべてのQtのコンテンツをレンダリングしたいなら、あなたはあなた自身のQPA(Qtのプラットフォーム抽象化)プラグインに基づいて、または派生を実装する方がよいかもしれません通常のWindows QPAプラグインから削除します。

は、その後、あなたは、(a)は、そこからあなたのペイントデバイスの実装を配布資料ことができ、任意のアプリケーション側のコードを必要とし、潜在的に

+0

HMMのDirect3Dを経由して、レンダリングQtQuickのシーングラフを取得するために、ANGLEのようなものを使用していません。私の目的のために本当に役立つように見えます。私はそれを試してみましょう、ありがとう!) –

+0

Qt 5.8はQtQuickの経験的なDirect3Dバックエンドを持っていますので、さらに見てください:http://blog.qt.io/blog/2016/08/15/the-qt -quick-graphics-stack-in-qt-5-8/ –

+0

Krammer私はすでにこの記事を読んでいますが、まだprocessEvents()でレンダリングされると思います。 DirectX11レンダリングが必要です。) –

関連する問題