Marco Hugentobler wrote: > I think that the WMS refresh problem is due to a problem with > QGraphicsView/QGraphicsRectItem, which I tried to adress with r7316. This fix > works for me on Kubuntu7.10, Win XP (msys) and Mac (G4). > > From what I can see, the synchronous requesting works as expected and is left > at the time QHttp sends the done() signal (once all the requested data is > available). The painting is then done into QImage, which I think is plattform > independent (software rendering). > > Asynchronous requesting of WMS layers could still be a possibility for the > future. Maybe combined with Tims idea of a composite manager? I think that > such functionality should be developed in a branch as there is a high risk of > side effects.
Hi Marco, r7316 doesn't fix the Mac WMS rendering problem; I am also using a Mac G4. To reproduce the bug, open a WMS layer and then resize or maximize the window. The layer is cleared and not redrawn. Other widgets such as the status and tool bars are sometimes drawn at incorrect locations too. Resizing a window by dragging the size control is a "gold standard" for testing Mac drawing code. If there are problems, they are most likely to show up while resizing a window. The problem is that the WMS implementation is not "Qt processEvent safe." Moving to asynchronous network events is one way to make the code processEvent safe. Moving the synchronous transfer outside the draw event might also work. Using threads for drawing is probably the best solution. I chose the asynchronous approach because it seemed closest to a bug fix than a redesign. This is the problematic sequence of events: 1. Resize window 2. WMS provider initiates draw event. 3. draw routine discovers layer needs refresh from WMS server. 4. draw routine issues network request. 5. QgsHttpTransaction calls processEvents so that network request can leave local machine. 6. processEvents now runs other events while waiting for the remote response. 7. there are drawing events pending due to setStatus signals from QgsHttpTransaction and QgsRasterLayer as well as for drawing the overview canvas. If a drag resize is in progress, there are also additional draw events due to the continued resizing of the main canvas. This is the bug -- a Mac draw event cannot be interrupted by another draw event. 8. eventually we resume interrupted draw events which are not able to be resumed. Here is the Mac terminal log: Warning: QWidget::repaint: Recursive repaint detected Warning: QCoreGraphicsPaintEngine::begin: Painter already active Warning: QPainter::begin(): Returned false Warning: QPainter::end: Painter not active, aborted followed by many of: Warning: QWidget: It is dangerous to leave painters active on a widget outside of the PaintEvent My guess is that the begin() of the second draw event is ignored as superfluous because the painter is already active. The second draw event then draws and successfully closes the painter. At this point, the resumed first draw is attempting to draw into an inactive painter. If we don't change anything, we need to tell users that QGIS/Mac does not support resizing or maximizing project windows containing WMS layers. I have been thinking along the same lines as Tim's composite manager but that's a bigger project than I want to do right now. It's probably best left for QGIS 1.1. For now, we should see if nested draw events can be eliminated without a major redesign. It would also be nice to have some development guidelines about processEvents since this problem keeps reappearing. A good rule would be that calls to processEvents cannot be made while drawing is in progress. Another good rule is not to allow QtPainter warnings in code which appears to work. These usually indicate code that is not cross-platform safe. Tom _______________________________________________ Qgis-user mailing list Qgis-user@lists.qgis.org http://lists.qgis.org/cgi-bin/mailman/listinfo/qgis-user