Как заставить Python ждать, пока QGIS рендерит шейп-файл - PullRequest
1 голос
/ 22 марта 2019

Я написал код для моего QGIS 2.8.1, который может успешно сделать снимок экрана с одним файлом формы, но, к сожалению, он не работает, когда я пытаюсь использовать несколько шейп-файлов.

Так что в основном, если я заменю allFiles = ["C:/Shapefiles/Map_00721.shp"]в приведенном ниже коде с 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"] цикл повторяется по массиву, не дожидаясь выполнения процесса рендеринга и моментального снимка.

Я попытался использовать time.sleep в приведенном ниже коде, но он также останавливает рендеринг шейп-файлови результат оказался не таким, как ожидалось.

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!"

1 Ответ

2 голосов
/ 26 марта 2019

Избегайте использования time.sleep(), так как это полностью остановит всю вашу программу. Вместо этого используйте processEvents(), который позволяет вашей программе отображаться в фоновом режиме.

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()

Этот метод должен хорошо работать для быстрого исправления, но в долгосрочной перспективе он может создать сложные проблемы для отслеживания. Лучше использовать QTimer с циклом событий для постоянного решения.

...