私はQML UIの使用に興味があるプロジェクトをいくつか持っています。 しかし、私たちがstandart Qtレンダリングシステムを使うだけでは不十分です。QCoreApplication :: processEvents()だけでなく、すべてのUI要素をすべてのフレームに再描画しようとする必要があります。カスタムグラフィックスエンジンを使用してQt QWidgetsとQMLを作成できますか?
これは、UIのバックグラウンドでDirectXをレンダリングするためです。
この場合、ウィジェットはQWidget :: render()関数のみを使用してレンダリングする方法を見つけましたが、この方法ではGPUの代わりにCPUを使用するため、速度が遅すぎ、まったく修正できません。
だから、私が持っているもの:
- 私ははQApplicationは自分のアプリケーションのループに統合できます。 信号/スロットシステムは正常に動作し、プロセスイベントは右 と呼ばれます。
- 他のレンダリングに使用する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:私の英語のため申し訳ありません)))
HMMのDirect3Dを経由して、レンダリングQtQuickのシーングラフを取得するために、ANGLEのようなものを使用していません。私の目的のために本当に役立つように見えます。私はそれを試してみましょう、ありがとう!) –
Qt 5.8はQtQuickの経験的なDirect3Dバックエンドを持っていますので、さらに見てください:http://blog.qt.io/blog/2016/08/15/the-qt -quick-graphics-stack-in-qt-5-8/ –
Krammer私はすでにこの記事を読んでいますが、まだprocessEvents()でレンダリングされると思います。 DirectX11レンダリングが必要です。) –