Navigation Menu

Skip to content

Commit

Permalink
Add convience method to block while canvas is rendering
Browse files Browse the repository at this point in the history
NOT to be called from anything but unit tests and standalone
scripts!!
  • Loading branch information
nyalldawson committed Mar 13, 2017
1 parent af532ec commit 9842fcb
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 59 deletions.
1 change: 1 addition & 0 deletions python/gui/qgsmapcanvas.sip
Expand Up @@ -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 );
Expand Down
8 changes: 8 additions & 0 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -2016,6 +2016,14 @@ void QgsMapCanvas::refreshAllLayers()
refresh();
}

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

void QgsMapCanvas::setSegmentationTolerance( double tolerance )
{
mSettings.setSegmentationTolerance( tolerance );
Expand Down
11 changes: 11 additions & 0 deletions src/gui/qgsmapcanvas.h
Expand Up @@ -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 );
Expand Down
74 changes: 15 additions & 59 deletions tests/src/python/test_qgsmapcanvas.py
Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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):
Expand Down

0 comments on commit 9842fcb

Please sign in to comment.