QOpenGLWidget Class

Die Klasse QOpenGLWidget ist ein Widget zum Rendern von OpenGL-Grafiken. Mehr...

Kopfzeile: #include <QOpenGLWidget>
CMake: find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets)
target_link_libraries(mytarget PRIVATE Qt6::OpenGLWidgets)
qmake: QT += openglwidgets
Vererbungen: QWidget

Öffentliche Typen

(since 6.5) enum TargetBuffer { LeftBuffer, RightBuffer }
enum UpdateBehavior { NoPartialUpdate, PartialUpdate }

Öffentliche Funktionen

QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
virtual ~QOpenGLWidget()
QOpenGLContext *context() const
(since 6.5) QOpenGLWidget::TargetBuffer currentTargetBuffer() const
GLuint defaultFramebufferObject() const
(since 6.5) GLuint defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const
void doneCurrent()
QSurfaceFormat format() const
QImage grabFramebuffer()
(since 6.5) QImage grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)
bool isValid() const
void makeCurrent()
(since 6.5) void makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)
void setFormat(const QSurfaceFormat &format)
void setTextureFormat(GLenum texFormat)
void setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)
GLenum textureFormat() const
QOpenGLWidget::UpdateBehavior updateBehavior() const

Signale

void aboutToCompose()
void aboutToResize()
void frameSwapped()
void resized()

Geschützte Funktionen

virtual void initializeGL()
virtual void paintGL()
virtual void resizeGL(int w, int h)

Reimplementierte geschützte Funktionen

virtual bool event(QEvent *e) override
virtual int metric(QPaintDevice::PaintDeviceMetric metric) const override
virtual QPaintEngine *paintEngine() const override
virtual void paintEvent(QPaintEvent *e) override
virtual QPaintDevice *redirected(QPoint *p) const override
virtual void resizeEvent(QResizeEvent *e) override

Detaillierte Beschreibung

QOpenGLWidget bietet Funktionalität zur Anzeige von OpenGL-Grafiken, die in eine Qt-Anwendung integriert sind. Es ist sehr einfach zu benutzen: Erben Sie Ihre Klasse davon und verwenden Sie die Unterklasse wie jede andere QWidget, mit der Ausnahme, dass Sie die Wahl zwischen der Verwendung von QPainter und Standard-OpenGL-Rendering-Befehlen haben.

QOpenGLWidget bietet drei bequeme virtuelle Funktionen, die Sie in Ihrer Unterklasse reimplementieren können, um die typischen OpenGL-Aufgaben auszuführen:

  • paintGL() - Rendert die OpenGL-Szene. Wird immer dann aufgerufen, wenn das Widget aktualisiert werden muss.
  • resizeGL() - Richtet das OpenGL-Ansichtsfenster, die Projektion, usw. ein. Wird aufgerufen, wenn die Größe des Widgets geändert wurde (und auch, wenn es zum ersten Mal angezeigt wird, da alle neu erstellten Widgets automatisch ein Größenänderungsereignis erhalten).
  • initializeGL() - Richtet die OpenGL-Ressourcen und den Status ein. Wird einmal aufgerufen, bevor resizeGL() oder paintGL() zum ersten Mal aufgerufen wird.

Wenn Sie eine Neuzeichnung von anderen Stellen als paintGL() auslösen müssen (ein typisches Beispiel ist die Verwendung von timers zur Animation von Szenen), sollten Sie die Funktion update() des Widgets aufrufen, um eine Aktualisierung zu planen.

Der OpenGL-Rendering-Kontext Ihres Widgets wird aktuell gemacht, wenn paintGL(), resizeGL() oder initializeGL() aufgerufen wird. Wenn Sie die Standard-OpenGL-API-Funktionen von anderen Stellen aus aufrufen müssen (z. B. im Konstruktor Ihres Widgets oder in Ihren eigenen Malfunktionen), müssen Sie zuerst makeCurrent() aufrufen.

Das gesamte Rendering erfolgt in ein OpenGL-Framebuffer-Objekt. makeCurrent() stellt sicher, dass es im Kontext gebunden ist. Behalten Sie dies im Hinterkopf, wenn Sie zusätzliche Framebuffer-Objekte im Rendering-Code in paintGL() erstellen und binden. Binden Sie niemals den Framebuffer mit der ID 0 neu. Rufen Sie stattdessen defaultFramebufferObject() auf, um die ID zu erhalten, die gebunden werden soll.

QOpenGLWidget erlaubt die Verwendung verschiedener OpenGL-Versionen und Profile, wenn die Plattform dies unterstützt. Setzen Sie einfach das gewünschte Format über setFormat(). Beachten Sie jedoch, dass mehrere QOpenGLWidget Instanzen im gleichen Fenster erfordern, dass sie alle das gleiche Format verwenden, oder zumindest Formate, die die Kontexte nicht nicht-zerlegbar machen. Um dieses Problem zu umgehen, verwenden Sie lieber QSurfaceFormat::setDefaultFormat() als setFormat().

Hinweis: Der Aufruf von QSurfaceFormat::setDefaultFormat() vor der Erstellung der QApplication Instanz ist auf einigen Plattformen (z.B. macOS) obligatorisch, wenn ein OpenGL-Kernprofilkontext angefordert wird. Damit soll sichergestellt werden, dass die gemeinsame Nutzung von Ressourcen zwischen Kontexten funktionsfähig bleibt, da alle internen Kontexte mit der richtigen Version und dem richtigen Profil erstellt werden.

Maltechniken

Wie oben beschrieben, können Sie die Unterklasse QOpenGLWidget zum Rendern reiner 3D-Inhalte auf folgende Weise verwenden:

  • Reimplementieren Sie die Funktionen initializeGL() und resizeGL(), um den OpenGL-Status einzurichten und eine perspektivische Transformation bereitzustellen.
  • Reimplementieren Sie paintGL(), um die 3D-Szene zu zeichnen, wobei nur OpenGL-Funktionen aufgerufen werden.

Es ist auch möglich, 2D-Grafiken auf eine QOpenGLWidget-Unterklasse mit QPainter zu zeichnen:

  • In paintGL(), anstatt OpenGL-Befehle auszugeben, konstruieren Sie ein QPainter Objekt zur Verwendung auf dem Widget.
  • Zeichnen Sie Primitive mit den Memberfunktionen von QPainter.
  • Direkte OpenGL-Befehle können weiterhin ausgegeben werden. Sie müssen jedoch sicherstellen, dass diese von einem Aufruf der beginNativePainting() und endNativePainting() des Painters eingeschlossen sind.

Wenn das Zeichnen nur mit QPainter durchgeführt wird, ist es auch möglich, das Malen wie bei normalen Widgets durchzuführen: durch Neuimplementierung von paintEvent().

  • Reimplementieren Sie die Funktion paintEvent().
  • Konstruieren Sie ein QPainter Objekt, das auf das Widget abzielt. Übergeben Sie das Widget entweder an den Konstruktor oder an die Funktion QPainter::begin().
  • Zeichnen Sie Primitive mit den Funktionen von QPainter.
  • Nach Beendigung des Zeichnens wird die Instanz QPainter zerstört. Alternativ können Sie auch QPainter::end() explizit aufrufen.

OpenGL Funktionsaufrufe, Header und QOpenGLFunctions

Wenn Sie OpenGL-Funktionen aufrufen, wird dringend empfohlen, den direkten Aufruf der Funktionen zu vermeiden. Verwenden Sie stattdessen lieber QOpenGLFunctions (wenn Sie portable Anwendungen erstellen) oder die versionierten Varianten (z.B. QOpenGLFunctions_3_2_Core und ähnliche, wenn Sie auf modernes, reines Desktop-OpenGL abzielen). Auf diese Weise wird die Anwendung in allen Qt-Build-Konfigurationen korrekt funktionieren, einschließlich derjenigen, die ein dynamisches Laden der OpenGL-Implementierung durchführen, was bedeutet, dass Anwendungen nicht direkt mit einer GL-Implementierung verknüpft werden und daher direkte Funktionsaufrufe nicht möglich sind.

In paintGL() ist der aktuelle Kontext immer durch den Aufruf von QOpenGLContext::currentContext() zugänglich. Aus diesem Kontext kann eine bereits initialisierte, gebrauchsfertige QOpenGLFunctions Instanz durch den Aufruf von QOpenGLContext::functions() abgerufen werden. Eine Alternative zum Voranstellen jedes GL-Aufrufs besteht darin, von QOpenGLFunctions zu erben und QOpenGLFunctions::initializeOpenGLFunctions() in initializeGL() aufzurufen.

Was die OpenGL-Header betrifft, so ist zu beachten, dass in den meisten Fällen keine Notwendigkeit besteht, Header wie GL.h direkt einzubinden. Die OpenGL-bezogenen Qt-Header werden qopengl.h einbinden, das wiederum einen geeigneten Header für das System einbinden wird. Dies kann ein OpenGL ES 3.x oder 2.0 Header sein, die höchste verfügbare Version, oder ein vom System bereitgestelltes gl.h. Zusätzlich wird eine Kopie der Erweiterungsheader (auf einigen Systemen glext.h genannt) als Teil von Qt sowohl für OpenGL als auch für OpenGL ES bereitgestellt. Diese werden auf den Plattformen, wo dies möglich ist, automatisch eingebunden. Das bedeutet, dass Konstanten und Funktionszeiger-Typendefinitionen von ARB-, EXT- und OES-Erweiterungen automatisch verfügbar sind.

Code-Beispiele

Für den Anfang könnte die einfachste QOpenGLWidget Unterklasse wie folgt aussehen:

class MyGLWidget : public QOpenGLWidget
{
public:
    MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }

protected:
    void initializeGL() override
    {
        // Set up the rendering context, load shaders and other resources, etc.:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        ...
    }

    void resizeGL(int w, int h) override
    {
        // Update projection matrix and other size related settings:
        m_projection.setToIdentity();
        m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
        ...
    }

    void paintGL() override
    {
        // Draw the scene:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClear(GL_COLOR_BUFFER_BIT);
        ...
    }

};

Alternativ kann die Präfixierung jedes einzelnen OpenGL-Aufrufs vermieden werden, indem man stattdessen von QOpenGLFunctions ableitet:

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    ...
    void initializeGL() override
    {
        initializeOpenGLFunctions();
        glClearColor(...);
        ...
    }
    ...
};

Um einen Kontext zu erhalten, der mit einer bestimmten OpenGL-Version oder einem Profil kompatibel ist, oder um Tiefen- und Stencil-Puffer anzufordern, rufen Sie setFormat() auf:

QOpenGLWidget *widget = new QOpenGLWidget(parent);
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
widget->setFormat(format); // must be called before the widget or its parent window gets shown

Hinweis: Es liegt an der Anwendung, sicherzustellen, dass Tiefen- und Schablonenpuffer von der zugrundeliegenden Windowing-System-Schnittstelle angefordert werden. Wenn keine Tiefenpuffergröße ungleich Null angefordert wird, gibt es keine Garantie, dass ein Tiefenpuffer verfügbar ist. Infolgedessen können OpenGL-Operationen im Zusammenhang mit Tiefenprüfungen nicht wie erwartet funktionieren. Übliche Anforderungen für Tiefen- und Schablonenpuffergrößen sind 24 bzw. 8.

In OpenGL 3.0+ Kontexten, wenn Portabilität nicht wichtig ist, bieten die versionierten QOpenGLFunctions Varianten einfachen Zugang zu allen modernen OpenGL Funktionen, die in einer bestimmten Version verfügbar sind:

    ...
    void paintGL() override
    {
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
        ...
        f->glDrawArraysInstanced(...);
        ...
    }
    ...

Wie oben beschrieben, ist es einfacher und robuster, das angeforderte Format global zu setzen, so dass es für alle Fenster und Kontexte während der Lebensdauer der Anwendung gilt. Nachfolgend ein Beispiel dafür:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 2);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);

    MyWidget widget;
    widget.show();

    return app.exec();
}

Multisampling

Um Multisampling zu aktivieren, setzen Sie die Anzahl der angeforderten Samples auf der QSurfaceFormat, die an setFormat() übergeben wird. Auf Systemen, die dies nicht unterstützen, kann die Anforderung ignoriert werden.

Multisampling-Unterstützung erfordert Unterstützung für Renderbuffer und Framebuffer-Blits mit mehreren Abtastungen. Auf OpenGL ES 2.0 Implementierungen ist es wahrscheinlich, dass diese nicht vorhanden sind. Dies bedeutet, dass Multisampling nicht verfügbar ist. Mit modernen OpenGL-Versionen und OpenGL ES 3.0 und höher ist dies normalerweise kein Problem mehr.

Threading

Das Durchführen von Offscreen-Rendering auf Worker-Threads, zum Beispiel um Texturen zu generieren, die dann im GUI/Haupt-Thread in paintGL() verwendet werden, wird unterstützt, indem die QOpenGLContext des Widgets offengelegt wird, so dass zusätzliche Kontexte, die sich mit ihm teilen, auf jedem Thread erstellt werden können.

Direktes Zeichnen auf den Framebuffer des QOpenGLWidgets außerhalb des GUI/Hauptthreads ist möglich, indem paintEvent() neu implementiert wird, um nichts zu tun. Die Thread-Affinität des Kontexts muss über QObject::moveToThread() geändert werden. Danach sind makeCurrent() und doneCurrent() auf dem Worker-Thread verwendbar. Achten Sie darauf, den Kontext anschließend wieder in den GUI/Hauptthread zu verschieben.

Das Auslösen eines Buffer Swaps nur für das QOpenGLWidget ist nicht möglich, da es keine echte, native Oberfläche auf dem Bildschirm dafür gibt. Es ist Aufgabe des Widget-Stacks, die Komposition und den Pufferwechsel im GUI-Thread zu verwalten. Wenn ein Thread mit der Aktualisierung des Framebuffers fertig ist, rufen Sie update() auf dem GUI/Haupt-Thread auf, um die Komposition zu planen.

Es muss besonders darauf geachtet werden, dass der Framebuffer nicht verwendet wird, wenn der GUI/Haupt-Thread das Compositing durchführt. Die Signale aboutToCompose() und frameSwapped() werden ausgegeben, wenn die Komposition beginnt und endet. Sie werden auf dem GUI/Haupt-Thread ausgegeben. Das bedeutet, dass aboutToCompose() durch die Verwendung einer direkten Verbindung den GUI/Haupt-Thread blockieren kann, bis der Worker-Thread sein Rendering beendet hat. Danach darf der Worker-Thread kein weiteres Rendering durchführen, bis das Signal frameSwapped() ausgegeben wird. Wenn dies nicht akzeptabel ist, muss der Worker-Thread einen doppelten Pufferungsmechanismus implementieren. Dies beinhaltet das Zeichnen unter Verwendung eines alternativen Rendering-Ziels, das vollständig durch den Thread kontrolliert wird, z.B. ein zusätzliches Framebuffer-Objekt, und das Blitten auf den Framebuffer des QOpenGLWidget zu einem geeigneten Zeitpunkt.

Gemeinsame Nutzung des Kontextes

Wenn mehrere QOpenGLWidgets als Kinder des gleichen Top-Level-Widgets hinzugefügt werden, teilen sich ihre Kontexte gegenseitig. Dies gilt nicht für QOpenGLWidget Instanzen, die zu verschiedenen Fenstern gehören.

Das bedeutet, dass alle QOpenGLWidgets im selben Fenster auf die gemeinsam nutzbaren Ressourcen der anderen zugreifen können, wie z.B. Texturen, und es besteht keine Notwendigkeit für einen extra "globalen Freigabe"-Kontext.

Um die gemeinsame Nutzung zwischen QOpenGLWidget Instanzen, die zu verschiedenen Fenstern gehören, einzurichten, setzen Sie das Qt::AA_ShareOpenGLContexts application Attribut bevor Sie QApplication instanzieren. Dies wird die Freigabe zwischen allen QOpenGLWidget Instanzen ohne weitere Schritte auslösen.

Das Erstellen von zusätzlichen QOpenGLContext Instanzen, die Ressourcen wie Texturen mit dem QOpenGLWidget Kontext teilen, ist ebenfalls möglich. Übergeben Sie einfach den von context() zurückgegebenen Zeiger an QOpenGLContext::setShareContext(), bevor Sie QOpenGLContext::create() aufrufen. Der resultierende Kontext kann auch in einem anderen Thread verwendet werden, was eine threaded Erzeugung von Texturen und asynchrone Textur-Uploads ermöglicht.

Beachten Sie, dass QOpenGLWidget eine standardkonforme Implementierung der gemeinsamen Nutzung von Ressourcen erwartet, wenn es um die zugrundeliegenden Grafiktreiber geht. Zum Beispiel haben einige Treiber, insbesondere für mobile und eingebettete Hardware, Probleme mit der Einrichtung der gemeinsamen Nutzung zwischen einem bestehenden Kontext und anderen, die später erstellt werden. Einige andere Treiber verhalten sich möglicherweise auf unerwartete Weise, wenn sie versuchen, gemeinsam genutzte Ressourcen zwischen verschiedenen Threads zu nutzen.

Initialisierung und Bereinigung von Ressourcen

Der zugehörige OpenGL-Kontext von QOpenGLWidget ist garantiert aktuell, wenn initializeGL() und paintGL() aufgerufen werden. Versuchen Sie nicht, OpenGL-Ressourcen zu erstellen, bevor initializeGL() aufgerufen wird. Zum Beispiel wird der Versuch, Shader zu kompilieren, Vertexpufferobjekte zu initialisieren oder Texturdaten hochzuladen, fehlschlagen, wenn dies im Konstruktor einer Unterklasse geschieht. Diese Operationen müssen auf initializeGL() verschoben werden. Einige der Qt OpenGL Hilfsklassen, wie QOpenGLBuffer oder QOpenGLVertexArrayObject, haben ein passendes aufgeschobenes Verhalten: sie können ohne Kontext instanziiert werden, aber alle Initialisierungen werden bis zu einem create() oder einem ähnlichen Aufruf aufgeschoben. Das bedeutet, dass sie als normale (Nicht-Pointer) Mitgliedsvariablen in einer QOpenGLWidget Unterklasse verwendet werden können, aber die create() oder ähnliche Funktion kann nur von initializeGL() aufgerufen werden. Seien Sie sich jedoch bewusst, dass nicht alle Klassen so gestaltet sind. Im Zweifelsfall machen Sie die Mitgliedsvariable zu einem Zeiger und erzeugen und zerstören die Instanz dynamisch in initializeGL() bzw. dem Destruktor.

Bei der Freigabe der Ressourcen muss auch der Kontext aktuell sein. Daher wird von Destruktoren, die solche Aufräumarbeiten durchführen, erwartet, dass sie makeCurrent() aufrufen, bevor sie mit der Zerstörung von OpenGL-Ressourcen oder Wrappern fortfahren. Vermeiden Sie aufgeschobenes Löschen über deleteLater() oder den Parenting-Mechanismus von QObject. Es gibt keine Garantie, dass der richtige Kontext zum Zeitpunkt der tatsächlichen Zerstörung der fraglichen Instanz aktuell ist.

Eine typische Unterklasse wird daher oft wie folgt aussehen, wenn es um die Initialisierung und Zerstörung von Ressourcen geht:

class MyGLWidget : public QOpenGLWidget
{
    ...

private:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram *m_program;
    QOpenGLShader *m_shader;
    QOpenGLTexture *m_texture;
};

MyGLWidget::MyGLWidget()
    : m_program(0), m_shader(0), m_texture(0)
{
    // No OpenGL resource initialization is done here.
}

MyGLWidget::~MyGLWidget()
{
    // Make sure the context is current and then explicitly
    // destroy all underlying OpenGL resources.
    makeCurrent();

    delete m_texture;
    delete m_shader;
    delete m_program;

    m_vbo.destroy();
    m_vao.destroy();

    doneCurrent();
}

void MyGLWidget::initializeGL()
{
    m_vao.create();
    if (m_vao.isCreated())
        m_vao.bind();

    m_vbo.create();
    m_vbo.bind();
    m_vbo.allocate(...);

    m_texture = new QOpenGLTexture(QImage(...));

    m_shader = new QOpenGLShader(...);
    m_program = new QOpenGLShaderProgram(...);

    ...
}

Dies funktioniert in den meisten Fällen, ist aber als generische Lösung nicht ganz ideal. Wenn das Widget reparented wird, so dass es in einem völlig anderen Top-Level-Fenster landet, wird etwas mehr benötigt: Durch die Verbindung mit dem aboutToBeDestroyed()-Signal von QOpenGLContext kann die Bereinigung immer dann durchgeführt werden, wenn der OpenGL-Kontext im Begriff ist, freigegeben zu werden.

Hinweis: Für Widgets, die ihr zugehöriges Top-Level-Fenster während ihrer Lebenszeit mehrfach wechseln, ist ein kombinierter Bereinigungsansatz, wie im folgenden Codeschnipsel gezeigt, unerlässlich. Immer wenn das Widget oder ein übergeordnetes Element reparented wird, so dass sich das Top-Level-Fenster ändert, wird der zugehörige Kontext des Widgets zerstört und ein neuer erstellt. Es folgt dann ein Aufruf von initializeGL(), bei dem alle OpenGL-Ressourcen neu initialisiert werden müssen. Aus diesem Grund besteht die einzige Möglichkeit, eine ordnungsgemäße Bereinigung durchzuführen, darin, sich mit dem Signal aboutToBeDestroyed() des Kontexts zu verbinden. Beachten Sie, dass der fragliche Kontext möglicherweise nicht der aktuelle ist, wenn das Signal ausgesendet wird. Daher ist es eine gute Praxis, makeCurrent() in dem verbundenen Slot aufzurufen. Zusätzlich müssen die gleichen Bereinigungsschritte vom Destruktor der abgeleiteten Klasse durchgeführt werden, da der mit dem Signal verbundene Slot oder Lambda nicht aufgerufen werden darf, wenn das Widget zerstört wird.

MyGLWidget::~MyGLWidget()
{
    cleanup();
}

void MyGLWidget::initializeGL()
{
    ...
    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

void MyGLWidget::cleanup()
{
    makeCurrent();
    delete m_texture;
    m_texture = 0;
    ...
    doneCurrent();
    disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

Hinweis: Wenn Qt::AA_ShareOpenGLContexts gesetzt ist, ändert sich der Kontext des Widgets niemals, auch nicht beim Reparenting, da die dem Widget zugeordnete Textur auch vom Kontext der neuen obersten Ebene aus zugänglich sein wird. Daher ist es nicht zwingend erforderlich, auf das aboutToBeDestroyed()-Signal des Kontextes zu reagieren, wenn dieses Flag gesetzt ist.

Korrektes Aufräumen ist wegen der gemeinsamen Nutzung von Kontexten besonders wichtig. Auch wenn der zugehörige QOpenGLWidget-Kontext zusammen mit dem QOpenGLWidget zerstört wird, bleiben die gemeinsam nutzbaren Ressourcen in diesem Kontext, wie z.B. Texturen, gültig, bis das Top-Level-Fenster, in dem das QOpenGLWidget lebte, zerstört wird. Zusätzlich können Einstellungen wie Qt::AA_ShareOpenGLContexts und einige Qt-Module einen noch größeren Bereich für die gemeinsame Nutzung von Kontexten auslösen, was dazu führen kann, dass die fraglichen Ressourcen für die gesamte Lebensdauer der Anwendung am Leben bleiben. Daher ist es am sichersten und robustesten, immer eine explizite Bereinigung für alle Ressourcen und Ressourcen-Wrapper durchzuführen, die im QOpenGLWidget verwendet werden.

Beschränkungen und andere Überlegungen

Andere Widgets darunter zu platzieren und das QOpenGLWidget transparent zu machen wird nicht zu den erwarteten Ergebnissen führen: Die Widgets darunter werden nicht sichtbar sein. Das liegt daran, dass in der Praxis das QOpenGLWidget vor allen anderen regulären, nicht-OpenGL Widgets gezeichnet wird, und daher sind durchsichtige Lösungen nicht möglich. Andere Arten von Layouts, wie z.B. Widgets über dem QOpenGLWidget, werden wie erwartet funktionieren.

Wenn es unbedingt notwendig ist, kann diese Einschränkung durch das Setzen des Qt::WA_AlwaysStackOnTop Attributs auf dem QOpenGLWidget überwunden werden. Seien Sie sich jedoch bewusst, dass dies die Stapelreihenfolge unterbricht, z.B. wird es nicht möglich sein, andere Widgets über dem QOpenGLWidget zu haben, so dass es nur in Situationen verwendet werden sollte, in denen ein halbtransparentes QOpenGLWidget mit anderen Widgets sichtbar darunter erforderlich ist.

Beachten Sie, dass dies nicht gilt, wenn es keine anderen Widgets darunter gibt und die Absicht ist, ein halbtransparentes Fenster zu haben. In diesem Fall ist der traditionelle Ansatz, Qt::WA_TranslucentBackground für das oberste Fenster zu setzen, ausreichend. Beachten Sie, dass wenn die transparenten Bereiche nur im QOpenGLWidget erwünscht sind, dann muss Qt::WA_NoSystemBackground nach der Aktivierung von Qt::WA_TranslucentBackground wieder auf false zurückgesetzt werden. Zusätzlich kann es, abhängig vom System, notwendig sein, einen Alphakanal für den QOpenGLWidget-Kontext über setFormat() anzufordern.

QOpenGLWidget unterstützt mehrere Update-Verhaltensweisen, genau wie QOpenGLWindow. Im konservierten Modus ist der gerenderte Inhalt des vorherigen paintGL()-Aufrufs im nächsten verfügbar, was inkrementelles Rendering ermöglicht. Im nicht-erhaltenen Modus geht der Inhalt verloren und von paintGL()-Implementierungen wird erwartet, dass sie alles in der Ansicht neu zeichnen.

Vor Qt 5.5 war das Standardverhalten von QOpenGLWidget, den gerenderten Inhalt zwischen paintGL() Aufrufen zu erhalten. Seit Qt 5.5 ist das Standardverhalten nicht-erhaltend, da dies eine bessere Leistung bietet und die Mehrheit der Anwendungen keinen Bedarf für den vorherigen Inhalt haben. Dies ähnelt auch der Semantik einer OpenGL-basierten QWindow und entspricht dem Standardverhalten von QOpenGLWindow, da die Farb- und Hilfspuffer für jedes Bild ungültig gemacht werden. Um das erhaltene Verhalten wiederherzustellen, rufen Sie setUpdateBehavior() mit PartialUpdate auf.

Hinweis: Beim dynamischen Hinzufügen eines QOpenGLWidgets in eine Widget-Hierarchie, z.B. durch Parenting eines neuen QOpenGLWidgets zu einem Widget, bei dem das entsprechende Top-Level-Widget bereits auf dem Bildschirm angezeigt wird, kann das zugehörige native Fenster implizit zerstört und neu erstellt werden, wenn das QOpenGLWidget das erste seiner Art innerhalb seines Fensters ist. Das liegt daran, dass sich der Fenstertyp von RasterSurface zu OpenGLSurface ändert und das hat plattformspezifische Auswirkungen. Dieses Verhalten ist neu in Qt 6.4.

Sobald ein QOpenGLWidget zu einer Widget-Hierarchie hinzugefügt wird, wird der Inhalt des Fensters der obersten Ebene über OpenGL-basiertes Rendering gespült. Andere Widgets als das QOpenGLWidget zeichnen ihren Inhalt weiterhin mit einem softwarebasierten Painter, aber die endgültige Zusammensetzung erfolgt über die 3D-API.

Hinweis: Die Anzeige eines QOpenGLWidgets erfordert einen Alphakanal im zugehörigen Backing Store des Top-Level-Fensters, da die Komposition mit anderen QWidget-basierten Inhalten funktioniert. Wenn kein Alphakanal vorhanden ist, wird der vom QOpenGLWidget gerenderte Inhalt nicht sichtbar sein. Dies kann besonders unter Linux/X11 in Remote-Display-Konfigurationen (z.B. mit Xvnc) relevant werden, wenn eine Farbtiefe kleiner als 24 verwendet wird. Eine Farbtiefe von 16 bedeutet zum Beispiel, dass ein Bild mit dem Format QImage::Format_RGB16 (RGB565) im Hintergrund gespeichert wird, was keinen Platz für einen Alphakanal lässt. Wenn Sie also Probleme damit haben, den Inhalt eines QOpenGLWidget korrekt mit anderen Widgets im Fenster zusammenzusetzen, vergewissern Sie sich, dass der Server (z. B. vncserver) mit einer Farbtiefe von 24 oder 32 Bit anstelle von 16 konfiguriert ist.

Alternativen

Das Hinzufügen eines QOpenGLWidgets in ein Fenster schaltet OpenGL-basiertes Compositing für das gesamte Fenster ein. In einigen speziellen Fällen kann dies nicht ideal sein, und das alte QGLWidget-artige Verhalten mit einem separaten, nativen Kindfenster ist erwünscht. Desktop-Anwendungen, die die Grenzen dieses Ansatzes kennen (z. B. in Bezug auf Überlappungen, Transparenz, Scroll-Ansichten und MDI-Bereiche), können QOpenGLWindow mit QWidget::createWindowContainer() verwenden. Dies ist eine moderne Alternative zu QGLWidget und ist schneller als QOpenGLWidget, da der zusätzliche Kompositionsschritt entfällt. Es wird dringend empfohlen, die Verwendung dieses Ansatzes auf Fälle zu beschränken, in denen es keine andere Wahl gibt. Beachten Sie, dass diese Option für die meisten eingebetteten und mobilen Plattformen nicht geeignet ist und auch auf bestimmten Desktop-Plattformen (z. B. macOS) Probleme auftreten können. Die stabile, plattformübergreifende Lösung ist immer QOpenGLWidget.

Stereoskopisches Rendering

Ab Version 6.5 bietet QOpenGLWidget Unterstützung für stereoskopisches Rendering. Um es zu aktivieren, setzen Sie das QSurfaceFormat::StereoBuffers Flag global, bevor das Fenster erstellt wird, mit QSurfaceFormat::SetDefaultFormat().

Hinweis: Die Verwendung von setFormat() wird nicht unbedingt funktionieren, da das Flag intern gehandhabt wird.

Dies wird dazu führen, dass paintGL() zweimal pro Frame aufgerufen wird, einmal für jedes QOpenGLWidget::TargetBuffer. Rufen Sie in paintGL() currentTargetBuffer() auf, um abzufragen, welches Bild gerade gezeichnet wird.

Hinweis: Um mehr Kontrolle über die linken und rechten Farbpuffer zu haben, sollten Sie stattdessen QOpenGLWindow + QWidget::createWindowContainer() verwenden.

Hinweis: Diese Art von 3D-Rendering hat bestimmte Hardwareanforderungen, z.B. muss die Grafikkarte mit Stereounterstützung eingerichtet sein.

OpenGL ist ein Warenzeichen von Silicon Graphics, Inc. in den Vereinigten Staaten und anderen Ländern.

Siehe auch QOpenGLFunctions, QOpenGLWindow, Qt::AA_ShareOpenGLContexts, und UpdateBehavior.

Dokumentation zum Elementtyp

[since 6.5] enum QOpenGLWidget::TargetBuffer

Gibt den zu verwendenden Puffer an, wenn das stereoskopische Rendering aktiviert ist, was durch die Einstellung QSurfaceFormat::StereoBuffers umgeschaltet wird.

Hinweis: LeftBuffer ist immer der Standardwert und wird als Fallback-Wert verwendet, wenn das stereoskopische Rendering deaktiviert ist oder vom Grafiktreiber nicht unterstützt wird.

KonstanteWert
QOpenGLWidget::LeftBuffer0
QOpenGLWidget::RightBuffer1

Diese Aufzählung wurde in Qt 6.5 eingeführt.

enum QOpenGLWidget::UpdateBehavior

Diese Aufzählung beschreibt die Aktualisierungssemantik von QOpenGLWidget.

KonstanteWertBeschreibung
QOpenGLWidget::NoPartialUpdate0QOpenGLWidget verwirft den Inhalt des Farbpuffers und der Hilfspuffer, nachdem QOpenGLWidget auf den Bildschirm gerendert wurde. Dies ist das gleiche Verhalten, das man erwarten kann, wenn man QOpenGLContext::swapBuffers mit einem standardmäßig Opengl-aktivierten QWindow als Argument aufruft. NoPartialUpdate kann einige Leistungsvorteile auf bestimmten Hardware-Architekturen haben, die im mobilen und eingebetteten Bereich üblich sind, wenn ein Framebuffer-Objekt als Rendering-Ziel verwendet wird. Das Framebuffer-Objekt wird zwischen den Frames mit glInvalidateFramebuffer (falls unterstützt) oder, als Fallback, glDiscardFramebufferEXT (falls unterstützt) oder einem Aufruf von glClear ungültig gemacht.
QOpenGLWidget::PartialUpdate1Die Framebuffer-Objekte Farbpuffer und Hilfspuffer werden zwischen den Frames nicht ungültig gemacht.

Siehe auch updateBehavior() und setUpdateBehavior().

Dokumentation der Mitgliedsfunktionen

[explicit] QOpenGLWidget::QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())

Konstruiert ein Widget, das ein Kind von parent ist, wobei die Widget-Flags auf f gesetzt sind.

[virtual noexcept] QOpenGLWidget::~QOpenGLWidget()

Zerstört die Instanz QOpenGLWidget und gibt ihre Ressourcen frei.

Der Kontext von QOpenGLWidget wird im Destruktor aktuell gemacht, was eine sichere Zerstörung jedes Kindobjekts ermöglicht, das OpenGL-Ressourcen freigeben muss, die zu dem von diesem Widget bereitgestellten Kontext gehören.

Warnung: Wenn Sie Objekte haben, die OpenGL-Ressourcen (wie QOpenGLBuffer, QOpenGLShaderProgram, usw.) als Mitglieder einer OpenGLWidget-Unterklasse umhüllen, müssen Sie möglicherweise auch einen Aufruf an makeCurrent() in den Destruktor dieser Unterklasse einfügen. Aufgrund der Regeln der C++-Objektzerstörung werden diese Objekte zerstört , bevor diese Funktion aufgerufen wird (aber nachdem der Destruktor der Unterklasse gelaufen ist), weshalb es für ihre sichere Entsorgung zu spät ist, den OpenGL-Kontext in dieser Funktion aktuell zu machen.

Siehe auch makeCurrent.

[signal] void QOpenGLWidget::aboutToCompose()

Dieses Signal wird ausgegeben, wenn das oberste Fenster des Widgets im Begriff ist, die Texturen seiner QOpenGLWidget Kinder und der anderen Widgets zu komponieren.

[signal] void QOpenGLWidget::aboutToResize()

Dieses Signal wird ausgegeben, wenn sich die Größe des Widgets ändert und daher das Framebuffer-Objekt neu erstellt werden muss.

QOpenGLContext *QOpenGLWidget::context() const

Rückgabe Die von diesem Widget verwendete QOpenGLContext oder 0, falls noch nicht initialisiert.

Hinweis: Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über setParent() repariert wird.

Siehe auch QOpenGLContext::setShareContext() und defaultFramebufferObject().

[since 6.5] QOpenGLWidget::TargetBuffer QOpenGLWidget::currentTargetBuffer() const

Gibt den derzeit aktiven Zielpuffer zurück. Dies ist standardmäßig der linke Puffer, der rechte Puffer wird nur verwendet, wenn QSurfaceFormat::StereoBuffers aktiviert ist. Wenn das stereoskopische Rendering aktiviert ist, kann dies in paintGL() abgefragt werden, um zu erfahren, welcher Puffer gerade verwendet wird. paintGL() wird zweimal aufgerufen, einmal für jedes Ziel.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch paintGL().

GLuint QOpenGLWidget::defaultFramebufferObject() const

Rückgabe Das Handle des Framebuffer-Objekts oder 0, falls es noch nicht initialisiert wurde.

Hinweis: Das Framebuffer-Objekt gehört zu dem von context() zurückgegebenen Kontext und ist möglicherweise von anderen Kontexten aus nicht zugänglich.

Hinweis: Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über setParent() repariert wird. Darüber hinaus ändert sich das Framebuffer-Objekt bei jeder Größenänderung.

Siehe auch context().

[since 6.5] GLuint QOpenGLWidget::defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const

Gibt das Framebuffer-Objekthandle des angegebenen Zielpuffers oder 0 zurück, wenn es noch nicht initialisiert wurde.

Der Aufruf dieser Überladung ist nur sinnvoll, wenn QSurfaceFormat::StereoBuffers aktiviert ist und von der Hardware unterstützt wird. Wenn nicht, gibt diese Methode den Standardpuffer zurück.

Hinweis: Das Framebuffer-Objekt gehört zu dem von context() zurückgegebenen Kontext und ist möglicherweise nicht von anderen Kontexten aus zugänglich. Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über setParent() repariert wird. Darüber hinaus ändert sich das Framebuffer-Objekt bei jeder Größenänderung.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch context().

void QOpenGLWidget::doneCurrent()

Gibt den Kontext frei.

In den meisten Fällen ist es nicht notwendig, diese Funktion aufzurufen, da das Widget beim Aufruf von paintGL() sicherstellt, dass der Kontext richtig gebunden und freigegeben wird.

[override virtual protected] bool QOpenGLWidget::event(QEvent *e)

Reimplements: QWidget::event(QEvent *Event).

QSurfaceFormat QOpenGLWidget::format() const

Gibt das von diesem Widget und seinem Toplevel-Fenster verwendete Kontext- und Oberflächenformat zurück.

Nachdem das Widget und sein Toplevel erstellt, in der Größe verändert und angezeigt wurden, gibt diese Funktion das aktuelle Format des Kontexts zurück. Dieses kann von dem angeforderten Format abweichen, wenn die Anforderung von der Plattform nicht erfüllt werden konnte. Es ist auch möglich, größere Farbpuffergrößen als angefordert zu erhalten.

Wenn das Fenster des Widgets und die zugehörigen OpenGL-Ressourcen noch nicht initialisiert sind, ist der Rückgabewert das Format, das über setFormat() gesetzt wurde.

Siehe auch setFormat() und context().

[signal] void QOpenGLWidget::frameSwapped()

Dieses Signal wird ausgegeben, nachdem das Top-Level-Fenster des Widgets den Aufbau beendet hat und von seinem möglicherweise blockierenden QOpenGLContext::swapBuffers()-Aufruf zurückgekehrt ist.

QImage QOpenGLWidget::grabFramebuffer()

Rendert ein 32-Bit-RGB-Bild des Framebuffers und gibt es zurück.

Hinweis: Dies ist eine potenziell teure Operation, da sie auf glReadPixels() angewiesen ist, um die Pixel zurückzulesen. Dies kann langsam sein und die GPU-Pipeline zum Stillstand bringen.

[since 6.5] QImage QOpenGLWidget::grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)

Rendert und gibt ein 32-Bit-RGB-Bild des Framebuffers des angegebenen Zielpuffers zurück. Diese Überladung ist nur sinnvoll, wenn QSurfaceFormat::StereoBuffers aktiviert ist. Das Erfassen des Framebuffers des richtigen Zielpuffers gibt das Standardbild zurück, wenn stereoskopisches Rendering deaktiviert ist oder von der Hardware nicht unterstützt wird.

Hinweis: Dies ist eine potentiell teure Operation, da sie auf glReadPixels() angewiesen ist, um die Pixel zurückzulesen. Dies kann langsam sein und die GPU-Pipeline zum Stillstand bringen.

Diese Funktion wurde in Qt 6.5 eingeführt.

[virtual protected] void QOpenGLWidget::initializeGL()

Diese virtuelle Funktion wird einmal vor dem ersten Aufruf von paintGL() oder resizeGL() aufgerufen. Reimplementieren Sie sie in einer Unterklasse.

Diese Funktion sollte alle erforderlichen OpenGL-Ressourcen einrichten.

Es besteht keine Notwendigkeit, makeCurrent() aufzurufen, da dies bereits geschehen ist, wenn diese Funktion aufgerufen wird. Beachten Sie jedoch, dass der Framebuffer zu diesem Zeitpunkt noch nicht verfügbar ist, vermeiden Sie also Zeichnungsaufrufe von hier aus. Verschieben Sie solche Aufrufe stattdessen auf paintGL().

Siehe auch paintGL() und resizeGL().

bool QOpenGLWidget::isValid() const

Gibt true zurück, wenn das Widget und die OpenGL-Ressourcen, wie der Kontext, erfolgreich initialisiert wurden. Beachten Sie, dass der Rückgabewert immer false ist, bis das Widget angezeigt wird.

void QOpenGLWidget::makeCurrent()

Bereitet das Rendern von OpenGL-Inhalten für dieses Widget vor, indem sie den entsprechenden Kontext aktuell macht und das Framebuffer-Objekt in diesen Kontext bindet.

In den meisten Fällen ist es nicht notwendig, diese Funktion aufzurufen, da sie automatisch vor dem Aufruf von paintGL() aufgerufen wird.

Siehe auch context(), paintGL(), und doneCurrent().

[since 6.5] void QOpenGLWidget::makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)

Bereitet das Rendern von OpenGL-Inhalten für dieses Widget vor, indem der Kontext für den übergebenen Puffer aktuell gemacht und das Framebuffer-Objekt in diesen Kontext eingebunden wird.

Hinweis: Dieser Aufruf ist nur sinnvoll, wenn das stereoskopische Rendering aktiviert ist. Es wird nichts passieren, wenn der richtige Puffer angefordert wird, obwohl er deaktiviert ist.

Es ist nicht notwendig, diese Funktion in den meisten Fällen aufzurufen, da sie automatisch vor dem Aufruf von paintGL() aufgerufen wird.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch context(), paintGL(), und doneCurrent().

[override virtual protected] int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const

Reimplements: QWidget::metric(QPaintDevice::PaintDeviceMetric m) const.

[override virtual protected] QPaintEngine *QOpenGLWidget::paintEngine() const

Reimplements: QWidget::paintEngine() const.

[override virtual protected] void QOpenGLWidget::paintEvent(QPaintEvent *e)

Reimplements: QWidget::paintEvent(QPaintEvent *event).

Behandelt Malereignisse.

Der Aufruf von QWidget::update() führt zum Senden eines Malereignisses e und damit zum Aufrufen dieser Funktion. (Anmerkung: Dies ist asynchron und geschieht irgendwann nach der Rückkehr von update()). Diese Funktion wird dann, nach einiger Vorbereitung, die virtuelle Funktion paintGL() aufrufen, um den Inhalt des Framebuffers von QOpenGLWidget zu aktualisieren. Das Top-Level-Fenster des Widgets wird dann die Textur des Framebuffers mit dem Rest des Fensters zusammensetzen.

[virtual protected] void QOpenGLWidget::paintGL()

Diese virtuelle Funktion wird immer dann aufgerufen, wenn das Widget gemalt werden muss. Reimplementieren Sie sie in einer Unterklasse.

Es besteht keine Notwendigkeit, makeCurrent() aufzurufen, da dies bereits geschehen ist, wenn diese Funktion aufgerufen wird.

Vor dem Aufruf dieser Funktion werden der Kontext und der Framebuffer gebunden, und das Ansichtsfenster wird durch einen Aufruf von glViewport() eingerichtet. Es wird kein anderer Status gesetzt und es wird kein Löschen oder Zeichnen durch das Framework durchgeführt.

Die Standardimplementierung führt ein glClear() aus. Von Unterklassen wird nicht erwartet, dass sie die Implementierung der Basisklasse aufrufen, sie sollten das Löschen selbst durchführen.

Hinweis: Um die Portabilität zu gewährleisten, sollten Sie nicht erwarten, dass der in initializeGL() gesetzte Zustand erhalten bleibt. Setzen Sie stattdessen alle notwendigen Zustände, zum Beispiel durch den Aufruf von glEnable(), in paintGL(). Der Grund dafür ist, dass einige Plattformen, wie z.B. WebAssembly mit WebGL, in manchen Situationen Einschränkungen für OpenGL-Kontexte haben, was dazu führen kann, dass der mit QOpenGLWidget verwendete Kontext auch für andere Zwecke verwendet wird.

Wenn QSurfaceFormat::StereoBuffers aktiviert ist, wird diese Funktion zweimal aufgerufen - einmal für jeden Puffer. Um herauszufinden, welcher Puffer gerade gebunden ist, rufen Sie currentTargetBuffer() auf.

Hinweis: Der Framebuffer jedes Ziels wird auch dann gezeichnet, wenn das stereoskopische Rendering von der Hardware nicht unterstützt wird. Nur der linke Puffer wird tatsächlich im Fenster sichtbar sein.

Siehe auch initializeGL(), resizeGL(), und currentTargetBuffer().

[override virtual protected] QPaintDevice *QOpenGLWidget::redirected(QPoint *p) const

[override virtual protected] void QOpenGLWidget::resizeEvent(QResizeEvent *e)

Reimplements: QWidget::resizeEvent(QResizeEvent *event).

Verarbeitet Größenänderungsereignisse, die mit dem Parameter e event übergeben werden. Ruft die virtuelle Funktion resizeGL() auf.

Hinweis: Vermeide es, diese Funktion in abgeleiteten Klassen zu überschreiben. Wenn das nicht möglich ist, stellen Sie sicher, dass auch die Implementierung von QOpenGLWidget aufgerufen wird. Andernfalls wird die Größe des zugrundeliegenden Framebuffer-Objekts und der zugehörigen Ressourcen nicht korrekt angepasst, was zu einer fehlerhaften Darstellung führt.

[virtual protected] void QOpenGLWidget::resizeGL(int w, int h)

Diese virtuelle Funktion wird immer dann aufgerufen, wenn die Größe des Widgets geändert wurde. Reimplementieren Sie sie in einer Unterklasse. Die neue Größe wird in w und h übergeben.

Es besteht keine Notwendigkeit, makeCurrent() aufzurufen, da dies bereits geschehen ist, wenn diese Funktion aufgerufen wird. Zusätzlich wird auch der Framebuffer gebunden.

Siehe auch initializeGL() und paintGL().

[signal] void QOpenGLWidget::resized()

Dieses Signal wird ausgegeben, nachdem das Framebuffer-Objekt aufgrund einer Größenänderung des Widgets neu erstellt wurde.

void QOpenGLWidget::setFormat(const QSurfaceFormat &format)

Legt die gewünschte Oberfläche format fest.

Wenn das Format nicht explizit über diese Funktion festgelegt wird, wird das von QSurfaceFormat::defaultFormat() zurückgegebene Format verwendet. Das bedeutet, dass bei mehreren OpenGL-Widgets die einzelnen Aufrufe dieser Funktion durch einen einzigen Aufruf von QSurfaceFormat::setDefaultFormat() ersetzt werden können, bevor das erste Widget erstellt wird.

Hinweis: Das Anfordern eines Alphapuffers über diese Funktion führt nicht zu den gewünschten Ergebnissen, wenn die Absicht ist, andere Widgets darunter sichtbar zu machen. Verwenden Sie stattdessen Qt::WA_AlwaysStackOnTop, um halbtransparente QOpenGLWidget Instanzen zu aktivieren, unter denen andere Widgets sichtbar sind. Beachten Sie jedoch, dass dies die Stapelreihenfolge aufhebt, so dass es nicht mehr möglich ist, andere Widgets über dem QOpenGLWidget zu haben.

Siehe auch format(), Qt::WA_AlwaysStackOnTop, und QSurfaceFormat::setDefaultFormat().

void QOpenGLWidget::setTextureFormat(GLenum texFormat)

Legt ein benutzerdefiniertes internes Texturformat von texFormat fest.

Wenn Sie mit sRGB-Framebuffern arbeiten, ist es notwendig, ein Format wie GL_SRGB8_ALPHA8 anzugeben. Dies kann durch den Aufruf dieser Funktion erreicht werden.

Hinweis: Diese Funktion hat keinen Effekt, wenn sie aufgerufen wird, nachdem das Widget bereits angezeigt wurde und somit die Initialisierung durchgeführt wurde.

Hinweis: Diese Funktion muss normalerweise in Kombination mit einem QSurfaceFormat::setDefaultFormat()-Aufruf verwendet werden, der den Farbraum auf QSurfaceFormat::sRGBColorSpace setzt.

Siehe auch textureFormat().

void QOpenGLWidget::setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)

Setzt das Aktualisierungsverhalten dieses Widgets auf updateBehavior.

Siehe auch updateBehavior().

GLenum QOpenGLWidget::textureFormat() const

Gibt das aktive interne Texturformat zurück, wenn das Widget bereits initialisiert wurde, das angeforderte Format, wenn eines gesetzt wurde, das Widget aber noch nicht sichtbar gemacht wurde, oder nullptr, wenn setTextureFormat() nicht aufgerufen wurde und das Widget noch nicht sichtbar gemacht wurde.

Siehe auch setTextureFormat().

QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const

Gibt das Aktualisierungsverhalten des Widgets zurück.

Siehe auch setUpdateBehavior().

© 2025 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.