QWidget::update() wird nicht ausgeführt
Verfasst: 14. April 2011 15:33
Hallo!
Ich arbeite an einer relativ umfangreichen Anwendung (Basis ist Qt 4.5.3), die ein Fenster mit einem OpenGL-Bereich (QGLWidget) enthält. Ein Thread ruft in regelmäßigen Abständen die update()-Methode dieses QGLWidgets auf.
Das Problem ist, dass das auch wunderbar eine Weile funktioniert, d.h. die OpenGL-Ansicht wird aktualisiert, aber irgendwann (zwischen ein paar Sekunden und ein paar Minuten) bleibt das Bild stehen.
Der Thread ruft dann immer noch brav update() auf, aber das löst nicht mehr einen Aufruf von paintEvent() aus.
Mit dem Debugger (Visual Studio 2005) habe ich mir angeschaut, was in der update()-Methode passiert. Dort landet er bei
und schließlich bei
paintOnScreen() liefert true und dirty.isEmpty() liefert false. Der else-if-Fall trifft auch nicht zu. Entsprechend der ersten Abfrage liefert nun isEmpty() auch wieder false und somit ist eventAlreadyPosted true, sodass auch das letzte if nicht zutrifft und die Funktion nichts tut und mit return zurückkehrt.
Ich interpretiere den Ablauf so, dass Qt schon weiß, dass bestimmte Teile des Bildschirms neu gezeichnet werden sollen, weil dirty nicht leer ist. Aber warum zeichnet er sie dann nicht neu?
Und warum tut er es anfangs und hört plötzlich damit auf?
Wenn ich das Fenster mal in den Hintergrund lege und dann wieder in den Vordergrung hole, wird es dann aber einmalig neu gezeichnet.
Ich arbeite an einer relativ umfangreichen Anwendung (Basis ist Qt 4.5.3), die ein Fenster mit einem OpenGL-Bereich (QGLWidget) enthält. Ein Thread ruft in regelmäßigen Abständen die update()-Methode dieses QGLWidgets auf.
Das Problem ist, dass das auch wunderbar eine Weile funktioniert, d.h. die OpenGL-Ansicht wird aktualisiert, aber irgendwann (zwischen ein paar Sekunden und ein paar Minuten) bleibt das Bild stehen.
Der Thread ruft dann immer noch brav update() auf, aber das löst nicht mehr einen Aufruf von paintEvent() aus.
Mit dem Debugger (Visual Studio 2005) habe ich mir angeschaut, was in der update()-Methode passiert. Dort landet er bei
Code: Alles auswählen
tlwExtra->backingStore->markDirty(rgn, this);Code: Alles auswählen
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
widget->d_func()->dirty = QRegion(rect);
sendUpdateRequest(widget, updateImmediately);
return;
} else if (qt_region_strictContains(widget->d_func()->dirty, rect)) {
if (updateImmediately)
sendUpdateRequest(widget, updateImmediately);
return; // Already dirty.
}
const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
widget->d_func()->dirty += rect;
if (!eventAlreadyPosted || updateImmediately)
sendUpdateRequest(widget, updateImmediately);
return;
}Ich interpretiere den Ablauf so, dass Qt schon weiß, dass bestimmte Teile des Bildschirms neu gezeichnet werden sollen, weil dirty nicht leer ist. Aber warum zeichnet er sie dann nicht neu?
Und warum tut er es anfangs und hört plötzlich damit auf?
Wenn ich das Fenster mal in den Hintergrund lege und dann wieder in den Vordergrung hole, wird es dann aber einmalig neu gezeichnet.