Aplicativos independentes usando QGIS e variáveis ​​de ambiente

12

Eu tentei passar pelo IRC para ver se as pessoas podem me ajudar com isso, mas o meio parece um pouco desajeitado para deixar as respostas claras, então vou tentar fazer isso.

Gostaria de programar um aplicativo independente usando o PyQGIS da maneira que já posso programar aplicativos independentes usando o ArcPy.

O próprio PyQGIS é direto. Não tive dificuldade em usar scripts Python em execução no editor de console do QGIS. No entanto, para usar as ligações Python em um script autônomo, sou aconselhado a alterar as configurações do ambiente usando um script em lote (estou usando o Windows Vista em casa, por isso estamos falando de scripts em lote para Windows). Isso resultou em uma bagunça do meu lado, pois eu realmente não entendo scripts em lote e não gosto da ideia de que estou redefinindo um ambiente que precisa ser uma certa maneira para outros aplicativos executados.

Estou tendo dificuldade para entender por que as instruções para criar essas configurações são desnecessariamente complicadas e por que não representam uma linha de código dizendo "vá para onde estão as ligações, disponibilize as bibliotecas que eu quero disponíveis para que este programa use Certamente, o ArcPy não exige que as pessoas mexam nas configurações ambientais do computador, por isso estou tendo dificuldade em entender o porquê do PyQGIS. Parece-me que as pessoas simplesmente desistem, em vez de aprenderem a linguagem de script de lote do Windows.

Agora, percebo que, quando executo um script no editor de console do QGIS, ele funciona. É verdade que isso também torna o restante do QGIS inutilizável após a execução do script, por isso tenho que reiniciar o QGIS novamente depois, mas o script funciona exatamente como eu o programava para funcionar. Mas quando faço isso fora do aplicativo QGIS, isso não acontece. O problema não parece ser o de que falhei ao importar algum pacote Python importado automaticamente pelo aplicativo QGIS (qgis.core e qgis.utils) - eu tenho essas instruções de importação no meu script independente, juntamente com todos os outros pacotes que importam o script requer. Isso me leva a acreditar que a diferença é que o aplicativo QGIS define corretamente variáveis ​​de ambiente externas, mas essas variáveis ​​não são definidas corretamente quando eu o executo como um script independente.

Além disso, quando executo o script como autônomo, ele passa por todo o código sem gerar um erro; simplesmente não faz o que o código ordena. Quando executo o script no editor do console, ele faz tudo corretamente. Quando o executo como autônomo, ele cria uma janela e a destrói imediatamente, sem gerar erros. Portanto, o intérprete entende tudo o que estou pedindo ao script - simplesmente não o fará.

Aqui está o script:

from PyQt4 import *
from PyQt4 import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.utils import *
import Tkinter
from Tkinter import *
import sys
import os

qgishome = "c:/OSGeo4W/apps/qgis/"
app = QgsApplication([], True)
QgsApplication.setPrefixPath(qgishome, True)
QgsApplication.initQgis()

canvas = QgsMapCanvas()
canvas.setCanvasColor(Qt.yellow)
canvas.enableAntiAliasing(True)
canvas.show()

layer = QgsVectorLayer(r"c:/GIS Data/fed308/cpc.shp", "Ridings", "ogr")
reg = QgsMapLayerRegistry.instance()
reg.addMapLayer(layer)
canvas.setExtent(layer.extent())
canvas.setLayerSet([QgsMapCanvasLayer(layer)])
QgsApplication.exitQgis()

Por favor ... existe alguma maneira de executar esse script fora do QGIS e fazê-lo funcionar como no QGIS (idealmente sem desligar as coisas no final)?

O QGIS é um programa maravilhoso, e o PyQGIS parece tão intuitivo quanto o ArcPy e seria uma vantagem real para um software de código aberto - mas se as pessoas tiverem que passar por todos os obstáculos que já passei e ainda não tiverem aplicativos independentes acesso às bibliotecas PyQGIS da maneira como elas têm acesso ao ArcPy, parece-me que o PyQGIS não será muito útil para as pessoas. Espero estar errado e isso é mais fácil do que foi até agora. Alguém tem uma solução?

Zak Klaas
fonte

Respostas:

6

Você precisa iniciar o loop de eventos Qt usando:

app.exec_()

Eu removeria QgsApplication.exitQgis (). Idealmente, ele deve ser manuseado em um slot conectado ao sinal lastWindowClosed () do aplicativo.

gsherman
fonte
Bom saber. Vou direcionar minhas energias para ler sobre o PyQt4, para que eu saiba mais o que preciso fazer para que qualquer GUI que eu tente no futuro funcione. Se G. Sherman, do script Script Runner, fama ... notei quando estava tentando executar esse código sem nenhuma das referências a QgsApplication e com o cabeçalho def run_script, o Script Runner precisa, meu script fez exatamente o que estava fazendo quando Eu estava tentando o script, como mostrado acima, como um script independente ... criando uma janela e fechando-a imediatamente. Isso foi parte do motivo pelo qual eu assumi que estava tendo problemas com variáveis ​​ambientais contínuas.
Zak Klaas
7

Consultando a documentação do PyQGis, você encontrará quatro maneiras principais de utilizar a API do PyQGis:

  1. via comandos no console do Python
  2. via scripts Python em Processing ou com o plug- in ScritRunner de Gary Sherman
  3. via desenvolvimento de plugins personalizados para o aplicativo QGis
  4. fora do QGIS (no shell do Python ou criando aplicativos com PyQt4 e não com o Tkinter (por que importar o Tkinter duas vezes?)

e você está interessado neste último ponto:

  • você pode usar o PyQGIS como qualquer outro módulo Python. Mas o Python não sabe onde encontrar o PyQGIS. Para isso, você precisa adicionar a pasta PyQGIS ao PYTHONPATH (para Windows, consulte Como adicionar ao pythonpath no Windows 7? ).

Certamente o ArcPy não exige que as pessoas mexam nas configurações ambientais do computador, por isso estou tendo dificuldade em entender por que o PyQGIS faz isso.

Como você usa a versão Python do ArcGIS, em outros casos, o mesmo é verdadeiro, procure usando arcpy outside arcmap ou Configure PyScripter para usar com QGIS (e ainda usar arcpy) no Windows , por exemplo.

Você não precisa aqui de PyQt4, Tkinter ou qgis.gui:

from qgis.core import *
QgsApplication.setPrefixPath("yourpath", True)
QgsApplication.initQgis()
# or your solution
# read a shapefile 
layer = QgsVectorLayer('your.shp', 'your', 'ogr')
layer.isValid()
True
# loop through layer 
for elem in layer.getFeatures():
    geom= elem.geometry()
    attr =elem.attributes()
    (processing)

 # interaction with other Python module: Shapely, for example
 from shapely.geometry import shape
 from json import loads
 for elem in layer.getFeatures():
       shapely_geometry = shape(loads(elem.geometry().exportToGeoJSON()))
  • você pode criar um aplicativo. Você precisa aqui do PyQt4 (e não do Tkinter) e do qgis.gui.

Gostaria de programar um aplicativo independente usando o PyQGIS da maneira que já posso programar aplicativos independentes usando o ArcPy.

Portanto, para isso, você deve aprender PyQt4, assim como aprender Tkinter (ou wxPython), por exemplo. Esse é outro problema: a solução dada por gsherman é um problema do PyQt4, não do PyQGIS (veja o tutorial do PyQt4 , por exemplo)

gene
fonte
Obrigado. Eu ainda não tinha ouvido alguém descrever o PyQt4 como algo que era uma espécie de alternativa exclusiva ao Tkinter, que eu sei muito bem agora (não sei por que o declarei duas vezes no código acima ... isso foi apenas um erro). Seu link para o tutorial do PyQt4 parece ser muito útil. Depois de experimentar hoje, eu eleito para resolver o meu problema por meio do editor de console e ter o script minimizar a janela do QGIS GUI para que a janela do meu roteiro parece ser um autônomo, com QGIS executado em segundo plano - então eu acho que é o número 1 na sua lista de 4 possibilidades.
Zak Klaas