I have written code for my QGIS 2.8.1
which can successfully take screenshot of one shape file, but unfortunately it doesn't work when I try with multiple shapefiles.
So basically if I replace allFiles = ["C:/Shapefiles/Map_00721.shp"]
in the code below with allFiles = ["C:/Shapefiles/Map_00721.shp", "C:/Shapefiles/Map_00711.shp", "C:/Shapefiles/Map_00731.shp", "C:/Shapefiles/Map_00791.shp", "C:/Shapefiles/Map_00221.shp"]
, the loop iterates over the array without waiting for the rendering and snapshot process to happen.
I have tried using time.sleep
in the code below, but it stops the rendering of shapefiles too and the result doesn't came as expected.
import ogr,os
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
import qgis.utils
import glob
from time import sleep
import math
import processing
from processing.core.Processing import Processing
from PyQt4.QtCore import QTimer
Processing.initialize()
Processing.updateAlgsList()
OutputFileName = "ABC" # Temprory global placeholder for filename
canvas = iface.mapCanvas()
def startstuffs():
qgis.utils.iface.zoomToActiveLayer() # Zoom to Layer
scale=canvas.scale() # Get current Scale
scale = scale * 1.5
canvas.zoomScale(scale) # Zoomout a bit
QTimer.singleShot(2000,saveImg) # Jump to save img
def saveImg():
qgis.utils.iface.mapCanvas().saveAsImage(OutputFileName)
QgsMapLayerRegistry.instance().removeAllMapLayers()
# Add array of address below
allFiles = ["C:/Shapefiles/Map_00721.shp"]
filesLen = len(allFiles)
TexLayer = "C:/US_County_NAD27.shp"
for lop in range(filesLen):
currentShpFile = allFiles[lop]
currentShpFileName = currentShpFile.strip("C:/Shapefiles/")
OutputFileName = "C:/ImageOut/" + currentShpFileName + ".png"
wb = QgsVectorLayer(currentShpFile, currentShpFileName, 'ogr')
wbTex = QgsVectorLayer(TexLayer, 'CountyGrid', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(wb) # Add the shapefile
QgsMapLayerRegistry.instance().addMapLayer(wbTex) # Add the county shapefile
qgis.utils.iface.setActiveLayer(wb) # Makes wb as active shapefile
QTimer.singleShot(3000, startstuffs) # This start stuffs
print "Done!"
Avoid using time.sleep()
since that will completely stall your entire program. Instead, use processEvents()
which allows your program to render in the background.
import time
def spin(seconds):
"""Pause for set amount of seconds, replaces time.sleep so program doesn't stall"""
time_end = time.time() + seconds
while time.time() < time_end:
QtGui.QApplication.processEvents()
This method should work fine for a quick fix, but in the long term it may generate difficult problems to track. It is better to use a QTimer with a event loop for a permanent solution.