QRhiWidget Class
Die Klasse „QRhiWidget“ ist ein Widget zur Darstellung von 3D-Grafiken über eine beschleunigte Grafik-API wie beispielsweise Vulkan, Metal oder Direct 3D. Mehr...
| Header: | #include <QRhiWidget> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Widgets) target_link_libraries(mytarget PRIVATE Qt6::Widgets) |
| qmake: | QT += widgets |
| Seit: | Qt 6.7 |
| Erbt von: | QWidget |
Öffentliche Typen
| enum class | Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 } |
| enum class | TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 } |
Eigenschaften
|
|
Öffentliche Funktionen
| QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}) | |
| virtual | ~QRhiWidget() override |
| QRhiWidget::Api | api() const |
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| QSize | fixedColorBufferSize() const |
| QImage | grabFramebuffer() const |
| bool | isDebugLayerEnabled() const |
| bool | isMirrorVerticallyEnabled() const |
| int | sampleCount() const |
| void | setApi(QRhiWidget::Api api) |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
| void | setDebugLayerEnabled(bool enable) |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
| void | setMirrorVertically(bool enabled) |
| void | setSampleCount(int samples) |
Signale
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
| void | frameSubmitted() |
| void | mirrorVerticallyChanged(bool enabled) |
| void | renderFailed() |
| void | sampleCountChanged(int samples) |
Geschützte Funktionen
| QRhiTexture * | colorTexture() const |
| QRhiRenderBuffer * | depthStencilBuffer() const |
| virtual void | initialize(QRhiCommandBuffer *cb) |
| QRhiRenderBuffer * | msaaColorBuffer() const |
| virtual void | releaseResources() |
| virtual void | render(QRhiCommandBuffer *cb) |
| QRhiRenderTarget * | renderTarget() const |
| QRhiTexture * | resolveTexture() const |
| QRhi * | rhi() const |
| void | setAutoRenderTarget(bool enabled) |
Neu implementierte geschützte Funktionen
| virtual bool | event(QEvent *e) override |
| virtual void | paintEvent(QPaintEvent *e) override |
| virtual void | resizeEvent(QResizeEvent *e) override |
Ausführliche Beschreibung
QRhiWidget bietet Funktionen zur Darstellung von 3D-Inhalten, die über die „ QRhi “-APIs gerendert werden, innerhalb einer auf „ QWidget “ basierenden Anwendung. In vielerlei Hinsicht ist es das portable Äquivalent zu „ QOpenGLWidget “, das nicht an eine einzelne 3D-Grafik-API gebunden ist, sondern mit allen von „ QRhi “ unterstützten APIs (wie Direct 3D 11/12, Vulkan, Metal und OpenGL) funktioniert.
Es wird erwartet, dass QRhiWidget unterklassifiziert wird. Um in die 2D-Textur zu rendern, die implizit vom QRhiWidget erstellt und verwaltet wird, sollten Unterklassen die virtuellen Funktionen „ initialize()“ und „ render()“ neu implementieren.
Die Größe der Textur passt sich standardmäßig an die Größe des Widgets an. Wenn eine feste Größe bevorzugt wird, legen Sie durch Aufruf von ` setFixedColorBufferSize()` eine feste Größe in Pixeln fest.
Zusätzlich zur Textur, die als Farbpuffer dient, werden implizit auch ein Tiefen-/Stencil-Puffer sowie ein Render-Target verwaltet, das diese miteinander verbindet.
Das „ QRhi “ für das oberste Fenster des Widgets ist standardmäßig so konfiguriert, dass es ein plattformspezifisches Backend und eine Grafik-API verwendet: Metal unter macOS und iOS, Direct 3D 11 unter Windows, ansonsten OpenGL. Rufen Sie „ setApi()“ auf, um dies zu überschreiben.
Hinweis: Ein einzelnes Widget-Fenster kann nur ein „ QRhi “-Backend und somit nur eine einzige 3D-Grafik-API verwenden. Wenn zwei „QRhiWidget“- oder „ QQuickWidget “-Widgets in der Widget-Hierarchie des Fensters unterschiedliche APIs anfordern, funktioniert nur eines davon korrekt.
Hinweis: Während QRhiWidget eine öffentliche Qt-API ist, bieten die Klassen der „ QRhi “-Familie im Qt GUI-Modul, darunter QRhi, QShader und QShaderDescription, nur begrenzte Kompatibilitätsgarantien. Für diese Klassen gibt es keine Garantien hinsichtlich der Quellcode- oder Binärkompatibilität, was bedeutet, dass die API nur mit der Qt-Version garantiert funktioniert, für die die Anwendung entwickelt wurde. Änderungen, die zu einer Inkompatibilität auf Quellcodeebene führen, sollen jedoch auf ein Minimum beschränkt bleiben und werden nur in Minor-Releases (6.7, 6.8 usw.) vorgenommen. „ qrhiwidget.h “ enthält keine Header-Dateien, die direkt mit „ QRhi “ in Zusammenhang stehen. Um diese Klassen bei der Implementierung einer QRhiWidget-Unterklasse zu verwenden, verknüpfen Sie mit Qt::GuiPrivate (bei Verwendung von CMake) und binden Sie die entsprechenden Header mit dem Präfix „ rhi “ ein, zum Beispiel #include <rhi/qrhi.h>.
Ein Beispiel für eine einfache QRhiWidget-Unterklasse, die ein Dreieck rendert, ist das folgende:
class ExampleRhiWidget : public QRhiWidget
{
public:
ExampleRhiWidget(QWidget *parent = nullptr) : QRhiWidget(parent) { }
void initialize(QRhiCommandBuffer *cb) override;
void render(QRhiCommandBuffer *cb) override;
private:
QRhi *m_rhi = nullptr;
std::unique_ptr<QRhiBuffer> m_vbuf;
std::unique_ptr<QRhiBuffer> m_ubuf;
std::unique_ptr<QRhiShaderResourceBindings> m_srb;
std::unique_ptr<QRhiGraphicsPipeline> m_pipeline;
QMatrix4x4 m_viewProjection;
float m_rotation = 0.0f;
};
float vertexData[] = {
0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
};
QShader getShader(const QString &name)
{
QFile f(name);
return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
}
void ExampleRhiWidget::initialize(QRhiCommandBuffer *cb)
{
if (m_rhi != rhi()) {
m_pipeline.reset();
m_rhi = rhi();
}
if (!m_pipeline) {
m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
m_vbuf->create();
m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64));
m_ubuf->create();
m_srb.reset(m_rhi->newShaderResourceBindings());
m_srb->setBindings({
QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()),
});
m_srb->create();
m_pipeline.reset(m_rhi->newGraphicsPipeline());
m_pipeline->setShaderStages({
{ QRhiShaderStage::Vertex, getShader(QLatin1String(":/shader_assets/color.vert.qsb")) },
{ QRhiShaderStage::Fragment, getShader(QLatin1String(":/shader_assets/color.frag.qsb")) }
});
QRhiVertexInputLayout inputLayout;
inputLayout.setBindings({
{ 5 * sizeof(float) }
});
inputLayout.setAttributes({
{ 0, 0, QRhiVertexInputAttribute::Float2, 0 },
{ 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
});
m_pipeline->setVertexInputLayout(inputLayout);
m_pipeline->setShaderResourceBindings(m_srb.get());
m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor());
m_pipeline->create();
QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
cb->resourceUpdate(resourceUpdates);
}
const QSize outputSize = colorTexture()->pixelSize();
m_viewProjection = m_rhi->clipSpaceCorrMatrix();
m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f);
m_viewProjection.translate(0, 0, -4);
}
void ExampleRhiWidget::render(QRhiCommandBuffer *cb)
{
QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
m_rotation += 1.0f;
QMatrix4x4 modelViewProjection = m_viewProjection;
modelViewProjection.rotate(m_rotation, 0, 1, 0);
resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData());
const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates);
cb->setGraphicsPipeline(m_pipeline.get());
const QSize outputSize = colorTexture()->pixelSize();
cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
cb->setShaderResources();
const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
cb->setVertexInput(0, 1, &vbufBinding);
cb->draw(3);
cb->endPass();
update();
}Dies ist ein Widget, das kontinuierlich Aktualisierungen anfordert, wobei die Frequenz durch die Darstellungsrate (vsync, abhängig von der Bildwiederholfrequenz des Bildschirms) gedrosselt wird. Wenn eine kontinuierliche Darstellung nicht gewünscht ist, sollte der Aufruf von ` update()` in ` render()` entfernt und stattdessen nur dann ausgeführt werden, wenn eine Aktualisierung des dargestellten Inhalts erforderlich ist. Sollte beispielsweise die Drehung des Würfels an den Wert eines „ QSlider “ gekoppelt werden, reicht es aus, das Signal für die Wertänderung des Schiebereglers mit einem Slot oder Lambda zu verbinden, das den neuen Wert weiterleitet und „ update()“ aufruft.
Die Vertex- und Fragment-Shader werden im Vulkan-Stil als GLSL bereitgestellt und müssen zunächst von der Qt-Shader-Infrastruktur verarbeitet werden. Dies geschieht entweder durch manuelles Ausführen des Befehlszeilentools „ qsb “ oder durch Verwendung der Funktion `qt_add_shaders()` in CMake. Die QRhiWidget-Implementierung lädt diese vorverarbeiteten „ .qsb “-Dateien, die im Lieferumfang der Anwendung enthalten sind. Weitere Informationen zur Shader-Übersetzungsinfrastruktur von Qt finden Sie unter Qt Shader Tools.
Der Quellcode für diese Shader könnte wie folgt aussehen:
color.vert
#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 v_color;
layout(std140, binding = 0) uniform buf {
mat4 mvp;
};
void main()
{
v_color = color;
gl_Position = mvp * position;
}color.frag
#version 440
layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 fragColor;
void main()
{
fragColor = vec4(v_color, 1.0);
}Das Ergebnis ist ein Widget, das Folgendes anzeigt:

Ein vollständiges, minimales Einführungsbeispiel finden Sie im Beispiel „Simple RHI Widget Example“.
Ein Beispiel mit mehr Funktionalität und einer Demonstration weiterer Konzepte finden Sie im Beispiel „Cube RHI Widget“.
Bei QRhiWidget erfolgt das Rendern immer in eine Backing-Textur und nicht direkt in das Fenster (die vom Fenstersystem für das native Fenster bereitgestellte Oberfläche oder Ebene). Dies ermöglicht eine korrekte Zusammenführung des Inhalts mit dem Rest der widgetbasierten Benutzeroberfläche und bietet eine einfache und kompakte API, die den Einstieg erleichtert. All dies geht jedoch auf Kosten zusätzlicher Ressourcen und kann sich möglicherweise auf die Leistung auswirken. In der Praxis ist dies oft völlig akzeptabel, doch fortgeschrittene Benutzer sollten die Vor- und Nachteile der verschiedenen Ansätze im Auge behalten. Weitere Informationen zu den beiden Ansätzen finden Sie im „RHI-Fenster-Beispiel“; vergleichen Sie dieses mit dem „Einfachen RHI-Widget-Beispiel “.
Das Umhängen eines QRhiWidgets in eine Widget-Hierarchie, die zu einem anderen Fenster gehört (Top-Level-Widget), oder das Machen des QRhiWidgets selbst zu einem Top-Level-Widget (durch Setzen des Elternelements auf ` nullptr`) beinhaltet das Ändern des zugehörigen ` QRhi ` (und möglicherweise das Zerstören des alten), während das QRhiWidget weiterhin aktiv und intakt bleibt. Um dies zu unterstützen, wird von robusten QRhiWidget-Implementierungen erwartet, dass sie auch die virtuelle Funktion ` releaseResources()` neu implementieren und ihre ` QRhi `-Ressourcen ebenso freigeben, wie sie es im Destruktor tun. Das Beispiel „Cube RHI Widget“ veranschaulicht dies in der Praxis.
Obwohl dies kein primärer Anwendungsfall ist, ermöglicht das QRhiWidget auch die Einbindung von Rendering-Code, der direkt eine 3D-Grafik-API wie Vulkan, Metal, Direct 3D oder OpenGL nutzt. Weitere Informationen zur Aufzeichnung nativer Befehle innerhalb eines „ QRhi “-Renderdurchlaufs finden Sie unter QRhiCommandBuffer::beginExternal(), und unter QRhiTexture::createFrom() wird beschrieben, wie Sie eine vorhandene native Textur „verpacken“ und diese anschließend in einem nachfolgenden Renderdurchlauf mit „ QRhi “ verwenden können. Beachten Sie jedoch, dass die Konfigurierbarkeit der zugrunde liegenden Grafik-API (ihre Geräte- oder Kontextfunktionen, Ebenen, Erweiterungen usw.) eingeschränkt sein wird, da das primäre Ziel von QRhiWidget darin besteht, eine für QRhi-basierten Rendering-Code geeignete Umgebung bereitzustellen, und nicht darin, beliebige, potenziell komplexe, fremde Rendering-Engines zu ermöglichen.
Siehe auch QRhi, QShader, QOpenGLWidget, „Einfaches RHI-Widget-Beispiel“ und „Cube-RHI-Widget-Beispiel“.
Dokumentation zu Mitgliedstypen
enum class QRhiWidget::Api
Legt die zu verwendende 3D-API und das „ QRhi “-Backend fest
| Konstante | Wert |
|---|---|
QRhiWidget::Api::Null | 0 |
QRhiWidget::Api::OpenGL | 1 |
QRhiWidget::Api::Metal | 2 |
QRhiWidget::Api::Vulkan | 3 |
QRhiWidget::Api::Direct3D11 | 4 |
QRhiWidget::Api::Direct3D12 | 5 |
Siehe auch „ QRhi “.
enum class QRhiWidget::TextureFormat
Legt das Format der Textur fest, in die der „ QRhiWidget “ rendert.
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhiWidget::TextureFormat::RGBA8 | 0 | Siehe „ QRhiTexture::RGBA8 “. |
QRhiWidget::TextureFormat::RGBA16F | 1 | Siehe „ QRhiTexture::RGBA16F “. |
QRhiWidget::TextureFormat::RGBA32F | 2 | Siehe QRhiTexture::RGBA32F. |
QRhiWidget::TextureFormat::RGB10A2 | 3 | Siehe QRhiTexture::RGB10A2. |
Siehe auch QRhiTexture.
Eigenschaftsdokumentation
autoRenderTarget : bool
Die aktuelle Einstellung für die automatische Verwaltung des Tiefen-Stencil-Puffers und des Renderziels.
Standardmäßig lautet der Wert „ true “.
colorBufferFormat : TextureFormat
Diese Eigenschaft steuert das Texturformat der Textur (oder des Renderbuffers), die als Farbpuffer verwendet wird. Der Standardwert ist „ TextureFormat::RGBA8 “. „ QRhiWidget “ unterstützt das Rendern in eine Teilmenge der von „ QRhiTexture “ unterstützten Formate. Es sollten nur Formate angegeben werden, die von „ QRhi::isTextureFormatSupported()“ als unterstützt gemeldet werden; andernfalls funktioniert das Rendern nicht.
Hinweis: Das Festlegen eines neuen Formats, wenn das Widget bereits initialisiert ist und gerendert wurde, bedeutet, dass alle vom Renderer erstellten QRhiGraphicsPipeline -Objekte unbrauchbar werden können, falls das zugehörige QRhiRenderPassDescriptor aufgrund des unterschiedlichen Texturformats nun inkompatibel ist. Ähnlich wie beim dynamischen Ändern von sampleCount bedeutet dies, dass die Implementierungen von initialize() oder render() sich dann um die Freigabe der bestehenden Pipelines und die Erstellung neuer Pipelines kümmern müssen.
Zugriffsfunktionen:
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
Notifier-Signal:
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
fixedColorBufferSize : QSize
Die feste Größe (in Pixeln) der zugehörigen Textur des „ QRhiWidget “. Relevant, wenn eine feste Texturgröße gewünscht wird, die nicht von der Größe des Widgets abhängt. Diese Größe hat keinen Einfluss auf die Geometrie des Widgets (seine Größe und Platzierung innerhalb des obersten Fensters), was bedeutet, dass der Inhalt der Textur auf den Bereich des Widgets gestreckt (vergrößert) oder verkleinert dargestellt wird.
Wird beispielsweise eine Größe festgelegt, die genau doppelt so groß ist wie die (Pixel-)Größe des Widgets, wird effektiv ein 2-faches Supersampling durchgeführt (Rendering mit doppelter Auflösung und anschließende implizite Verkleinerung beim Texturieren des dem Widget im Fenster entsprechenden Quadrats). Andererseits bewirkt die Festlegung einer Größe, die der Hälfte der Widget-Größe entspricht, effektiv ein Rendern mit halber Auflösung und anschließendes Hochskalieren der Ergebnisse.
Standardmäßig ist der Wert ein Null- QSize. Ein Null- oder leerer QSize bedeutet, dass die Größe der Textur der Größe des QRhiWidget s folgt. (texture size = widget size * device pixel ratio).
Hinweis: Das Gerätepixelverhältnis (der Skalierungsfaktor des System-Compositors) kann einen großen Einfluss auf die Leistung haben, da ein Skalierungsfaktor von 2 (200 %) bedeutet, dass mit doppelter Auflösung gerendert wird – also doppelt so groß, wie Entwickler und UI-Designer die Größe des Widgets wahrnehmen – und der Inhalt anschließend effektiv verkleinert wird, ähnlich wie bei der Einstellung dieser Eigenschaft auf das Doppelte der Pixelgröße des Widgets in einem System, in dem das Gerätepixelverhältnis 1 beträgt. Daher ist zu erwarten, dass diese Eigenschaft nur selten mit Größen verwendet wird, die größer sind als die Pixelgröße des Widgets, da viele moderne Desktop-Systeme weder den Bedarf noch die Leistungsreserven dafür haben, wenn vom System ohnehin ein Gerätepixelverhältnis von mehr als 1 verwendet wird. Stattdessen besteht der Hauptanwendungsfall für diese Eigenschaft darin, eine kleinere Größe festzulegen, um mit einer angemessen geringeren Auflösung zu rendern, anstatt blind der Fenstergeometrie zu folgen, wie groß diese auch sein mag.
Zugriffsfunktionen:
| QSize | fixedColorBufferSize() const |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
Notifier-Signal:
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
mirrorVertically : bool
Wenn diese Option aktiviert ist, wird das Bild beim Zusammenfügen der Hintergrundtextur des „ QRhiWidget “ mit dem übrigen Widget-Inhalt im obersten Fenster um die X-Achse gespiegelt.
Der Standardwert ist „ false “.
Zugriffsfunktionen:
| bool | isMirrorVerticallyEnabled() const |
| void | setMirrorVertically(bool enabled) |
Notifier-Signal:
| void | mirrorVerticallyChanged(bool enabled) |
sampleCount : int
Diese Eigenschaft steuert die Anzahl der Abtastungen für das Multisample-Antialiasing. Standardmäßig ist der Wert „ 1 “, was bedeutet, dass MSAA deaktiviert ist.
Gültige Werte sind 1, 4, 8 und manchmal 16 sowie 32. Mit „ QRhi::supportedSampleCounts()“ können die unterstützten Sample-Zahlen zur Laufzeit abgefragt werden, doch in der Regel sollten Anwendungen 1 (kein MSAA), 4x (normales MSAA) oder 8x (hohes MSAA) anfordern.
Hinweis: Die Festlegung eines neuen Werts bedeutet, dass alle vom Renderer erstellten QRhiGraphicsPipeline -Objekte fortan dieselbe Sample-Anzahl verwenden müssen. Bestehende „ QRhiGraphicsPipeline “-Objekte, die mit einer anderen Sample-Anzahl erstellt wurden, dürfen nicht mehr verwendet werden. Wenn sich der Wert ändert, werden alle Farb- und Tiefen-Stencil-Puffer automatisch zerstört und neu erstellt, und „ initialize()“ wird erneut aufgerufen. Wenn jedoch „ autoRenderTarget “ auf „ false “ gesetzt ist, obliegt es der Anwendung, dies in Bezug auf den Tiefen-Stencil-Puffer oder zusätzliche Farbpuffer zu verwalten.
Das Ändern der Sample-Anzahl vom Standardwert 1 auf einen höheren Wert bedeutet, dass ` colorTexture()` zu ` nullptr ` wird und ` msaaColorBuffer()` nun ein gültiges Objekt zurückgibt. Das Zurücksetzen auf 1 (oder 0) hat den gegenteiligen Effekt: Beim nächsten Aufruf von ` initialize()` gibt ` msaaColorBuffer()` ` nullptr` zurück, während ` colorTexture()` wieder gültig wird. Darüber hinaus gibt „ resolveTexture()“ immer dann einen gültigen (nicht-Multisample-) QRhiTexture zurück, wenn die Sample-Anzahl größer als 1 ist (d. h., wenn MSAA verwendet wird).
Zugriffsfunktionen:
| int | sampleCount() const |
| void | setSampleCount(int samples) |
Benachrichtigungssignal:
| void | sampleCountChanged(int samples) |
Siehe auch „ msaaColorBuffer()“ und „ resolveTexture()“.
Dokumentation der Mitgliedsfunktionen
[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})
Erstellt ein Widget, das ein untergeordnetes Element von ` parent` ist, wobei die Widget-Flags auf ` f` gesetzt sind.
[override virtual noexcept] QRhiWidget::~QRhiWidget()
Destruktor.
QRhiWidget::Api QRhiWidget::api() const
Gibt die aktuell eingestellte Grafik-API zurück (QRhi -Backend).
Siehe auch setApi().
[protected] QRhiTexture *QRhiWidget::colorTexture() const
Gibt die Textur zurück, die als Farbpuffer für das Widget dient.
Darf nur von ` initialize()` und ` render()` aufgerufen werden.
Im Gegensatz zum Depth-Stencil-Puffer und dem ` QRhiRenderTarget` ist diese Textur immer verfügbar und wird vom ` QRhiWidget` verwaltet, unabhängig vom Wert von ` autoRenderTarget`.
Hinweis: Wenn „ sampleCount “ größer als 1 ist und somit Multisample-Antialiasing aktiviert ist, lautet der Rückgabewert „ nullptr “. Abfragen Sie stattdessen den Wert von „ QRhiRenderBuffer “ durch Aufruf von „ msaaColorBuffer()“.
Hinweis: Die Größeder zugrunde liegenden Textur und die Anzahl der Samples können auch über den von ` renderTarget()` zurückgegebenen Wert ` QRhiRenderTarget ` abgefragt werden. Dies kann bequemer und kompakter sein als die Abfrage über ` QRhiTexture ` oder ` QRhiRenderBuffer`, da es unabhängig davon funktioniert, ob Multisampling verwendet wird oder nicht.
Siehe auch msaaColorBuffer(), depthStencilBuffer(), renderTarget() und resolveTexture().
[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const
Gibt den Depth-Stencil-Puffer zurück, der für die Darstellung des Widgets verwendet wird.
Darf nur von ` initialize()` und ` render()` aufgerufen werden.
Nur verfügbar, wenn autoRenderTarget gleich true ist. Andernfalls ist der Rückgabewert nullptr, und es obliegt der Neuimplementierung von initialize(), einen Tiefen-Stencil-Puffer und einen QRhiTextureRenderTarget zu erstellen und zu verwalten.
Siehe auch colorTexture() und renderTarget().
[override virtual protected] bool QRhiWidget::event(QEvent *e)
Umsetzt: ` QWidget::event(QEvent *event)`.
[signal] void QRhiWidget::frameSubmitted()
Dieses Signal wird ausgelöst, nachdem das oberste Fenster des Widgets die Komposition abgeschlossen hat und sich im Status „ submitted a frame “ befindet.
QImage QRhiWidget::grabFramebuffer() const
Rendert ein neues Bild, liest den Inhalt der Textur zurück und gibt ihn als ` QImage` zurück.
Wenn ein Fehler auftritt, wird ein null- QImage zurückgegeben.
Das zurückgegebene ` QImage ` hat das Format ` QImage::Format_RGBA8888`, ` QImage::Format_RGBA16FPx4`, ` QImage::Format_RGBA32FPx4` oder ` QImage::Format_BGR30`, abhängig von ` colorBufferFormat()`.
QRhiWidget kennt die Vorgehensweise des Renderers bei der Überblendung und Komposition nicht und kann daher nicht wissen, ob die Ausgabe in den RGB-Farbwerten mit Alpha-Kanal vorvervielfacht ist. Daher werden die Formate _Premultiplied und QImage niemals für das zurückgegebene QImage verwendet, selbst wenn dies angemessen wäre. Es obliegt dem Aufrufer, die resultierenden Daten nach eigenem Ermessen neu zu interpretieren.
Hinweis: Diese Funktion kann auch aufgerufen werden, wenn der QRhiWidget nicht zu einer Widget-Hierarchie hinzugefügt wurde, die zu einem Top-Level-Fenster auf dem Bildschirm gehört. Dies ermöglicht die Erzeugung eines Bildes aus einem 3D-Rendering außerhalb des Bildschirms.
Die Funktion heißt grabFramebuffer(), um die Konsistenz mit QOpenGLWidget und QQuickWidget zu wahren. Dies ist nicht die einzige Möglichkeit, CPU-seitige Bilddaten aus dem Inhalt des QRhiWidget zu extrahieren: Der Aufruf von QWidget::grab() auf einem QRhiWidget oder einem dessen Vorfahren funktioniert ebenfalls (und gibt ein QPixmap zurück). Neben der direkten Arbeit mit ` QImage` besteht ein weiterer Vorteil von `grabFramebuffer()` darin, dass es möglicherweise etwas leistungsfähiger ist, einfach weil es nicht den Rest der ` QWidget `-Infrastruktur durchlaufen muss, sondern sofort das Rendern eines neuen Frames auslösen und anschließend das Zurücklesen durchführen kann.
Siehe auch setColorBufferFormat().
[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)
Wird aufgerufen, wenn das Widget zum ersten Mal initialisiert wird, wenn sich die Größe, das Format oder die Anzahl der Samples der zugehörigen Textur ändert oder wenn sich die „ QRhi “ und die Textur aus irgendeinem Grund ändern. Von der Funktion wird erwartet, dass sie die vom Rendering-Code in ` render()` verwendeten Grafikressourcen verwaltet (erstellt, falls noch nicht vorhanden, anpasst und neu erstellt, falls sich die Größe geändert hat).
Um den „ QRhi “, „ QRhiTexture “ und andere zugehörige Objekte abzufragen, rufen Sie „ rhi()“, „ colorTexture()“, „ depthStencilBuffer()“ und „ renderTarget()“ auf.
Wenn sich die Größe des Widgets ändert, sind das ` QRhi `-Objekt, die Farbpuffer-Textur sowie die Objekte für den Tiefen- und Stencil-Puffer zwar dieselben Instanzen wie zuvor (sodass die Getter dieselben Zeiger zurückgeben), doch wurden die Farb- sowie die Tiefen- und Stencil-Puffer wahrscheinlich neu aufgebaut, was bedeutet, dass sich ` size ` und die zugrunde liegende native Texturressource möglicherweise von denen beim letzten Aufruf unterscheiden.
Reimplementierungen sollten zudem darauf vorbereitet sein, dass sich das „ QRhi “-Objekt und die Farbpuffertextur zwischen den Aufrufen dieser Funktion ändern können. Ein Sonderfall, in dem die Objekte unterschiedlich sind, tritt auf, wenn ein „ grabFramebuffer()“ mit einem noch nicht angezeigten Widget durchgeführt wird und das Widget anschließend innerhalb eines Top-Level-Widgets auf dem Bildschirm sichtbar gemacht wird. Dort erfolgt die Erfassung mit einem dedizierten ` QRhi `, das dann bei nachfolgenden Aufrufen von `initialize()` und ` render()` durch das zugehörige ` QRhi ` des Top-Level-Fensters ersetzt wird. Ein weiterer, häufigerer Fall tritt auf, wenn das Widget einem neuen Top-Level-Fenster zugeordnet wird. In diesem Fall sind das ` QRhi ` und alle zugehörigen Ressourcen, die vom ` QRhiWidget ` verwaltet werden, beim nachfolgenden Aufruf dieser Funktion andere Instanzen als zuvor. Es ist daher wichtig, dass alle vorhandenen ` QRhi `-Ressourcen, die zuvor von der Unterklasse erstellt wurden, zerstört werden, da sie zum vorherigen ` QRhi ` gehören, das vom Widget nicht mehr verwendet werden sollte.
Wenn „ autoRenderTarget “ auf „ true “ gesetzt ist – was die Standardeinstellung ist –, werden ein Depth-Stencil- QRhiRenderBuffer und ein „ QRhiTextureRenderTarget “, die mit „ colorTexture()“ (oder „ msaaColorBuffer(“)) verknüpft sind, sowie der Depth-Stencil-Puffer automatisch erstellt und verwaltet. Reimplementierungen von „initialize()“ und „ render()“ können diese Objekte über „ depthStencilBuffer()“ und „ renderTarget()“ abfragen. Wenn „ autoRenderTarget “ auf „ false “ gesetzt ist, werden diese Objekte nicht mehr automatisch erstellt und verwaltet. Stattdessen obliegt es der Implementierung von `initialize()`, Puffer zu erstellen und das Renderziel nach eigenem Ermessen einzurichten. Bei der manuellen Verwaltung zusätzlicher Farb- oder Tiefen-Stencil-Anhänge für das Renderziel müssen deren Größe und Sample-Anzahl stets der Größe und Sample-Anzahl von ` colorTexture()` bzw. ` msaaColorBuffer()` entsprechen; andernfalls können Fehler beim Rendern oder bei der Validierung durch die 3D-API auftreten.
Es wird erwartet, dass die von der Unterklasse erstellten Grafikressourcen in der Destruktor-Implementierung der Unterklasse freigegeben werden.
cb ist der „ QRhiCommandBuffer “ für den aktuellen Frame des Widgets. Die Funktion wird aufgerufen, während ein Frame aufgezeichnet wird, jedoch ohne aktiven Render-Pass. Der Befehlspuffer dient in erster Linie dazu, „ resource updates “ in die Warteschlange einzureihen, ohne auf „ render()“ zurückzugreifen.
Siehe auch ` render()`.
bool QRhiWidget::isDebugLayerEnabled() const
Gibt „true“ zurück, wenn eine Debug- oder Validierungsschicht angefordert wird, sofern dies für die verwendete Grafik-API zutrifft.
Siehe auch ` setDebugLayerEnabled()`.
[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const
Gibt den Renderbuffer zurück, der als Multisample-Farbpuffer für das Widget dient.
Darf nur von „ initialize()“ und „ render()“ aufgerufen werden.
Wenn ` sampleCount ` größer als 1 ist und somit Multisample-Antialiasing aktiviert ist, hat der zurückgegebene ` QRhiRenderBuffer ` eine entsprechende Sample-Anzahl und dient als Farbpuffer. Grafikpipelines, die zum Rendern in diesen Puffer verwendet werden, müssen mit derselben Sample-Anzahl erstellt werden, und die Sample-Anzahl des Depth-Stencil-Puffers muss ebenfalls übereinstimmen. Es wird erwartet, dass der Multisample-Inhalt in die von ` resolveTexture()` zurückgegebene Textur aufgelöst wird. Wenn ` autoRenderTarget ` auf ` true` gesetzt ist, wird ` renderTarget()` automatisch entsprechend eingerichtet, indem `msaaColorBuffer()` als ` renderbuffer ` der Farbzuordnung 0 und ` resolveTexture()` als deren ` resolveTexture` festgelegt werden.
Wenn MSAA nicht verwendet wird, lautet der Rückgabewert „ nullptr “. Verwenden Sie in diesem Fall stattdessen „ colorTexture()“.
Je nach der zugrunde liegenden 3D-Grafik-API gibt es möglicherweise keinen praktischen Unterschied zwischen Multisample-Texturen und Farb-Renderbuffern mit einer Sample-Anzahl größer als 1 (QRhi ordnet möglicherweise beide einfach demselben nativen Ressourcentyp zu). Einige ältere APIs unterscheiden jedoch möglicherweise zwischen Texturen und Renderbuffern. Um OpenGL ES 3.0 zu unterstützen, wo Multisample-Renderbuffer verfügbar sind, Multisample-Texturen jedoch nicht, führt QRhiWidget MSAA immer unter Verwendung eines Multisample- QRhiRenderBuffer s als Farb-Attachment durch (und niemals eines Multisample- QRhiTexture s).
Hinweis: Die Größeder Backing-Textur und die Anzahl der Samples können auch über den von renderTarget() zurückgegebenen QRhiRenderTarget abgefragt werden. Dies kann bequemer und kompakter sein als die Abfrage über den QRhiTexture oder den QRhiRenderBuffer, da es unabhängig davon funktioniert, ob Multisampling verwendet wird oder nicht.
Siehe auch colorTexture(), depthStencilBuffer(), renderTarget() und resolveTexture().
[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)
Implementiert: ` QWidget::paintEvent` (`QPaintEvent *event`).
Behandelt Zeichenereignisse.
Der Aufruf von ` QWidget::update()` führt zum Senden eines Zeichenereignisses ` e` und damit zum Aufruf dieser Funktion. Das Senden des Ereignisses erfolgt asynchron und findet zu einem Zeitpunkt nach der Rückkehr aus ` update()` statt. Diese Funktion ruft dann nach einigen Vorbereitungen die virtuelle Funktion ` render()` auf, um den Inhalt der mit dem ` QRhiWidget` verknüpften Textur zu aktualisieren. Das oberste Fenster des Widgets fügt die Textur anschließend mit dem Rest des Fensters zusammen.
[virtual protected] void QRhiWidget::releaseResources()
Wird aufgerufen, wenn die Grafikressourcen vorzeitig freigegeben werden müssen.
Dies tritt normalerweise nicht bei einem „ QRhiWidget “ auf, das der Kindhierarchie eines Top-Level-Widgets hinzugefügt wird und dort für den Rest seiner Lebensdauer sowie der des Top-Level-Widgets verbleibt. Daher ist es in vielen Fällen nicht erforderlich, diese Funktion neu zu implementieren, z. B. weil die Anwendung immer nur ein einziges Top-Level-Widget (natives Fenster) besitzt. Wenn jedoch eine Umordnung des Widgets (oder eines seiner Vorfahren) stattfindet, wird die Neuimplementierung dieser Funktion in robusten, gut geschriebenen Unterklassen von ` QRhiWidget ` erforderlich.
Wenn diese Funktion aufgerufen wird, wird von der Implementierung erwartet, dass sie alle Ressourcen von „ QRhi “ (Objekte vom Typ „QRhiBuffer “, „ QRhiTexture “ usw.) freigibt, ähnlich wie dies im Destruktor erwartet wird. Das Setzen auf NULL, die Verwendung eines Smart-Pointers oder das Setzen eines „ resources-invalid “-Flags ist ebenfalls erforderlich, da „ initialize()“ anschließend aufgerufen wird. Beachten Sie jedoch, dass es falsch ist, die Freigabe von Ressourcen auf den nachfolgenden Aufruf von ` initialize()` zu verschieben. Wenn diese Funktion aufgerufen wird, muss die Ressource vor der Rückkehr freigegeben werden. Beachten Sie außerdem, dass die Implementierung dieser Funktion den Klassen-Destruktor (oder Smart-Pointer) nicht ersetzt: Die Grafikressourcen müssen weiterhin in beiden Fällen freigegeben werden.
Ein Beispiel hierfür in der Praxis finden Sie im Beispiel „Cube RHI Widget “. Dort löst die Schaltfläche, die den „ QRhiWidget “ zwischen dem Status als untergeordnetes Widget (da es ein übergeordnetes Widget hat) und dem Status als Widget der obersten Ebene (da es kein übergeordnetes Widget hat) umschaltet, den Aufruf dieser Funktion aus, da sich das zugehörige Widget der obersten Ebene, das native Fenster, und „ QRhi “ sich alle während der Lebensdauer des „ QRhiWidget “ ändern, wobei das zuvor verwendete „ QRhi “ zerstört wird, was eine vorzeitige Freigabe der zugehörigen Ressourcen zur Folge hat, die vom noch aktiven „ QRhiWidget “ verwaltet werden.
Ein weiterer Fall, in dem diese Funktion aufgerufen wird, tritt ein, wenn ` grabFramebuffer()` mit einem ` QRhiWidget ` verwendet wird, das keinem sichtbaren Fenster hinzugefügt wurde, d. h., die Darstellung erfolgt außerhalb des Bildschirms. Wird dieses ` QRhiWidget ` später sichtbar gemacht oder einer sichtbaren Widget-Hierarchie hinzugefügt, wechselt der zugehörige ` QRhi ` von dem für die Offscreen-Darstellung verwendeten temporären zu dem für das Fenster bestimmten, wodurch ebenfalls diese Funktion ausgelöst wird.
Siehe auch ` initialize()`.
[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)
Wird aufgerufen, wenn der Inhalt des Widgets (d. h. der Inhalt der Textur) aktualisiert werden muss.
Es erfolgt immer mindestens ein Aufruf von ` initialize()` (), bevor diese Funktion aufgerufen wird.
Um Aktualisierungen anzufordern, rufen Sie ` QWidget::update()` auf. Der Aufruf von ` update()` innerhalb von `render()` führt zu einer kontinuierlichen Aktualisierung, die durch Vsync gedrosselt wird.
cb ist die ` QRhiCommandBuffer ` für den aktuellen Frame des Widgets. Die Funktion wird aufgerufen, während ein Frame aufgezeichnet wird, jedoch ohne aktiven Render-Durchlauf.
Siehe auch initialize().
[signal] void QRhiWidget::renderFailed()
Dieses Signal wird immer dann ausgelöst, wenn das Widget auf seine Hintergrundtextur gerendert werden soll (entweder aufgrund eines „ widget update “ oder aufgrund eines Aufrufs von „ grabFramebuffer()“), aber keine „ QRhi “ für das Widget zur Verfügung steht, was wahrscheinlich auf Probleme im Zusammenhang mit der Grafikkonfiguration zurückzuführen ist.
Dieses Signal kann bei Auftreten eines Problems mehrfach ausgelöst werden. Gehen Sie nicht davon aus, dass es nur einmal ausgelöst wird. Verwenden Sie „ Qt::SingleShotConnection “, wenn der Fehlerbehandlungscode nur einmal benachrichtigt werden soll.
[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const
Gibt das Render-Target-Objekt zurück, das bei Neaimplementierungen von ` render()` zusammen mit ` QRhiCommandBuffer::beginPass()` verwendet werden muss.
Darf nur von ` initialize()` und ` render()` aufgerufen werden.
Nur verfügbar, wenn ` autoRenderTarget ` gleich ` true` ist. Andernfalls lautet der Rückgabewert ` nullptr `, und es obliegt der Neuimplementierung von ` initialize()` (), einen Depth-Stencil-Puffer und einen ` QRhiTextureRenderTarget` zu erstellen und zu verwalten.
Beim Erstellen von „ graphics pipelines “ wird ein „ QRhiRenderPassDescriptor “ benötigt. Dieser kann über den zurückgegebenen „ QRhiTextureRenderTarget “ durch Aufruf von „ renderPassDescriptor()“ abgefragt werden.
Siehe auch colorTexture() und depthStencilBuffer().
[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)
Implementiert: ` QWidget::resizeEvent(QResizeEvent *event)`.
Behandelt Größenänderungsereignisse, die über den Ereignisparameter „ e “ übergeben werden. Ruft die virtuelle Funktion „ initialize()“ auf.
Hinweis: Vermeiden Sie es, diese Funktion in abgeleiteten Klassen zu überschreiben. Sollte dies nicht möglich sein, stellen Sie sicher, dass auch die Implementierung von ` QRhiWidget` aufgerufen wird. Andernfalls werden das zugrunde liegende Texturobjekt und die zugehörigen Ressourcen nicht korrekt in der Größe angepasst, was zu einer fehlerhaften Darstellung führt.
[protected] QRhiTexture *QRhiWidget::resolveTexture() const
Gibt die Nicht-Multisample-Textur zurück, auf die der Multisample-Inhalt aufgelöst wird.
Das Ergebnis ist „ nullptr “, wenn Multisample-Antialiasing nicht aktiviert ist.
Darf nur von „ initialize()“ und „ render()“ aufgerufen werden.
Bei aktiviertem MSAA ist dies die Textur, die mit dem restlichen „ QWidget “-Inhalt auf dem Bildschirm zusammengesetzt wird. Das Rendering von „ QRhiWidget “ muss jedoch auf das (Multisample-)„ QRhiRenderBuffer “ abzielen, das von „ msaaColorBuffer()“ zurückgegeben wird. Wenn „ autoRenderTarget “ auf „ true “ gesetzt ist, wird dies durch das von „ renderTarget()“ zurückgegebene „ QRhiRenderTarget “ übernommen. Andernfalls ist es Aufgabe des Unterklassen-Codes, ein Render-Target-Objekt korrekt zu konfigurieren, das sowohl den Farbpuffer als auch die aufgelösten Texturen enthält.
Siehe auch ` colorTexture()`.
[protected] QRhi *QRhiWidget::rhi() const
Gibt das aktuelle „ QRhi “-Objekt zurück.
Darf nur von „ initialize()“ und „ render()“ aufgerufen werden.
void QRhiWidget::setApi(QRhiWidget::Api api)
Legt die zu verwendende Grafik-API und das Backend „ QRhi “ auf „ api “ fest.
Warnung: Diese Funktion muss früh genug aufgerufen werden, bevor das Widget zu einer Widget-Hierarchie hinzugefügt und auf dem Bildschirm angezeigt wird. Versuchen Sie beispielsweise, die Funktion im Konstruktor der Unterklasse aufzurufen. Wird die Funktion zu spät aufgerufen, hat sie keine Wirkung.
Der Standardwert hängt von der Plattform ab: Metal unter macOS und iOS, Direct 3D 11 unter Windows, ansonsten OpenGL.
Die „ api “ kann für das Widget und dessen oberstes Fenster nur einmal festgelegt werden. Sobald dies geschehen ist und in Kraft tritt, kann das Fenster zum Rendern nur noch diese API und das „ QRhi “-Backend verwenden. Der Versuch, einen anderen Wert festzulegen oder ein weiteres „ QRhiWidget “ mit einer anderen „ api “ hinzuzufügen, funktioniert nicht wie erwartet.
Siehe auch setColorBufferFormat(), setDebugLayerEnabled() und api().
[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)
Legt fest, ob ein Tiefen-Stencil- QRhiRenderBuffer und ein QRhiTextureRenderTarget vom Widget automatisch erstellt und verwaltet werden. Der Standardwert ist „ true “.
Im automatischen Modus richten sich die Größe und die Anzahl der Samples des Depth-Stencil-Puffers nach den Einstellungen der Farbpuffer-Textur. Im nicht-automatischen Modus geben „ renderTarget()“ und „ depthStencilBuffer()“ stets „ nullptr “ zurück, und es obliegt dann der Implementierung von „ initialize()“ in der Anwendung, die Einrichtung und Verwaltung dieser Objekte zu übernehmen.
Rufen Sie diese Funktion frühzeitig auf – beispielsweise im Konstruktor der abgeleiteten Klasse –, wobei ` enabled ` auf ` false ` gesetzt sein muss, um den automatischen Modus zu deaktivieren.
void QRhiWidget::setDebugLayerEnabled(bool enable)
Fordert die Debug- oder Validierungsschicht der zugrunde liegenden Grafik-API an, wenn „ enable “ auf „true“ gesetzt ist.
Warnung: Diese Funktion muss früh genug aufgerufen werden, bevor das Widget zu einer Widget-Hierarchie hinzugefügt und auf dem Bildschirm angezeigt wird. Versuchen Sie beispielsweise, die Funktion im Konstruktor der Unterklasse aufzurufen. Wird die Funktion zu spät aufgerufen, hat sie keine Wirkung.
Gilt für Vulkan und Direct 3D.
Standardmäßig ist diese Funktion deaktiviert.
Siehe auch „ setApi()“ und „ isDebugLayerEnabled()“.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.