Skip to content
Permalink
Browse files

Add convience method to block while canvas is rendering

NOT to be called from anything but unit tests and standalone
scripts!!
  • Loading branch information
nyalldawson committed Mar 13, 2017
1 parent af532ec commit 9842fcbfc76a8d7b27f22784bcb3168914f0162e
Showing with 35 additions and 59 deletions.
  1. +1 −0 python/gui/qgsmapcanvas.sip
  2. +8 −0 src/gui/qgsmapcanvas.cpp
  3. +11 −0 src/gui/qgsmapcanvas.h
  4. +15 −59 tests/src/python/test_qgsmapcanvas.py
@@ -30,6 +30,7 @@ class QgsMapCanvas : QGraphicsView
bool isCachingEnabled() const;
void clearCache();
void refreshAllLayers();
void waitWhileRendering();
void setParallelRenderingEnabled( bool enabled );
bool isParallelRenderingEnabled() const;
void setMapUpdateInterval( int timeMilliseconds );
@@ -2016,6 +2016,14 @@ void QgsMapCanvas::refreshAllLayers()
refresh();
}

void QgsMapCanvas::waitWhileRendering()
{
while ( mRefreshScheduled || mJob )
{
QgsApplication::processEvents();
}
}

void QgsMapCanvas::setSegmentationTolerance( double tolerance )
{
mSettings.setSegmentationTolerance( tolerance );
@@ -128,6 +128,17 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! @note added in 2.9
void refreshAllLayers();

/**
* Blocks until the rendering job has finished.
*
* In almost all cases you do NOT want to call this, as it will hang the UI
* until the rendering job is complete. It's included in API solely for
* unit testing and standalone python scripts.
*
* @note added in QGIS 3.0
*/
void waitWhileRendering();

//! Set whether the layers are rendered in parallel or sequentially
//! @note added in 2.4
void setParallelRenderingEnabled( bool enabled );
@@ -58,13 +58,10 @@ def testDeferredUpdate(self):
canvas.setLayers([layer])
canvas.setExtent(QgsRectangle(10, 30, 20, 35))
canvas.show()

# need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()

canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))

# add polygon to layer
@@ -83,10 +80,7 @@ def testDeferredUpdate(self):

# refresh canvas
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()

# now we expect the canvas check to fail (since they'll be a new polygon rendered over it)
self.assertFalse(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))
@@ -110,9 +104,7 @@ def testRefreshOnTimer(self):
# need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()

canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))

# add polygon to layer
@@ -210,9 +202,7 @@ def testMapTheme(self):
# need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()

canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

# add some styles
@@ -223,18 +213,12 @@ def testMapTheme(self):
layer.styleManager().addStyleFromLayer('style2')

canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

layer.styleManager().setCurrentStyle('style1')
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

# ok, so all good with setting/rendering map styles
@@ -258,18 +242,12 @@ def testMapTheme(self):

canvas.setTheme('theme2')
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

canvas.setTheme('theme1')
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

# add another layer
@@ -286,17 +264,11 @@ def testMapTheme(self):

# rerender canvas - should NOT show new layer
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))
# test again - this time refresh all layers
canvas.refreshAllLayers()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

# add layer 2 to theme1
@@ -305,10 +277,7 @@ def testMapTheme(self):
QgsProject.instance().mapThemeCollection().update('theme1', theme1)

canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

# change the appearance of an active style
@@ -320,42 +289,29 @@ def testMapTheme(self):
QgsProject.instance().mapThemeCollection().update('theme1', theme1)

canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

layer2.styleManager().setCurrentStyle('style4')
sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'})
layer2.renderer().setSymbol(sym3)
canvas.refresh()

while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

# try setting layers while a theme is in place
canvas.setLayers([layer])
canvas.refresh()

# should be no change... setLayers should be ignored if canvas is following a theme!
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

# setLayerStyleOverrides while theme is in place
canvas.setLayerStyleOverrides({layer2.id(): 'original'})
# should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme!
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
canvas.waitWhileRendering()
self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

def canvasImageCheck(self, name, reference_image, canvas):

0 comments on commit 9842fcb

Please sign in to comment.
You can’t perform that action at this time.