8  Parte VI - Projecto prático

8.1 28. Construir o Quick Point Logger

O repositório deste manual inclui examples/quick_point_logger, um plugin pedagógico que combina:

  • acção verificável;
  • ferramenta de clique;
  • camada de memória;
  • transformação para WGS 84;
  • painel simples;
  • exportação GeoJSON;
  • definições persistentes;
  • compatibilidade básica Qt 5/6.

8.1.1 28.1 Passo 1 - criar a pasta

quick_point_logger/
├── __init__.py
├── metadata.txt
├── plugin.py
├── dock.py
├── utils.py
├── icons/capture.svg
├── LICENSE
└── README.md

8.1.2 28.2 Passo 2 - metadata e entrada

Implemente metadata.txt e classFactory() com a estrutura mostrada nos capítulos 4 e 5.

8.1.3 28.3 Passo 3 - acção e ferramenta

Crie uma acção verificável, associe ao menu Vector e à toolbar. Quando activada, defina QgsMapToolEmitPoint no canvas.

8.1.4 28.4 Passo 4 - camada e campos

Crie a camada WGS 84 e adicione campos de tempo, coordenadas e nota. Transforme o clique antes de escrever.

8.1.5 28.5 Passo 5 - painel

Inclua:

  • nota para próxima captura;
  • número de pontos;
  • iniciar/parar;
  • undo;
  • exportar.

8.1.6 28.6 Passo 6 - testes

Teste:

  • metadata;
  • versão;
  • estrutura;
  • função DMS;
  • nome de ficheiro;
  • ausência de imports directos PyQt5/PyQt6.

8.1.7 28.7 Passo 7 - pacote

python -m compileall -q quick_point_logger
python -m unittest discover -s tests -v
zip -qr quick_point_logger-0.1.0.zip quick_point_logger \
  -x '*/__pycache__/*' '*.pyc'

8.2 29. Exercícios graduais

8.2.1 Básico

  1. Alterar nome, ícone e mensagem da acção.
  2. Adicionar um campo operator.
  3. Guardar a última nota com QgsSettings.
  4. Validar se a camada está activa.

8.2.2 Intermédio

  1. Permitir seleccionar camada de destino com QgsMapLayerComboBox.
  2. Adicionar exportação GeoPackage.
  3. Implementar undo da última feição.
  4. Adicionar snapping do projecto.
  5. Criar tabela de registos.

8.2.3 Avançado

  1. Executar exportação pesada em QgsTask.
  2. Adicionar geocodificação reversa assíncrona com cache.
  3. Criar testes AST para enums Qt.
  4. Adicionar tradução português/inglês.
  5. Criar release automática por tag.
  6. Preparar submissão ao repositório oficial.

8.3 30. Diagnóstico de erros

O diagnóstico deve começar pelo ciclo de vida: confirmar se o pacote foi descoberto, se classFactory() importou a classe, se initGui() terminou e se a operação específica recebeu entradas válidas. Depois consulte Log Messages, a consola Python e o traceback completo. Os padrões abaixo cobrem as falhas mais comuns.

  • Plugin não aparece: metadata inválida ou pasta instalada no nível errado. Verifique metadata.txt, o nome da pasta e a localização no perfil.
  • Erro em classFactory(): import relativo, nome da classe ou dependência indisponível. Teste o import na consola Python do QGIS.
  • Erro em initGui(): enum Qt, recurso ausente, caminho de ícone ou widget incompatível. Valide todos os ficheiros do pacote no QGIS 3 e 4.
  • Interface congela: processamento pesado executado no thread principal. Mova o lote para QgsTask e actualize widgets apenas no callback final.
  • Coordenadas erradas: ponto do canvas tratado directamente como longitude/latitude. Transforme do CRS do projecto para EPSG:4326.
  • Output bloqueado: camada aberta no QGIS ou ficheiro utilizado por outra aplicação. Remova a camada, feche o programa e repita.
  • Snapping não ocorre: configuração, tolerância, visibilidade ou transformação de CRS incorrecta. Teste o snapping do projecto e o fallback separadamente.
  • Rede falha apenas no QGIS: pedido feito com biblioteca que ignora o proxy da aplicação. Use QgsNetworkAccessManager.
  • QGIS fecha ou produz erro ao desactivar: tarefa, reply ou map tool continuam activos. Cancele, aborte e remova tudo em unload().
  • ZIP rejeitado: directório de topo, metadata, licença, versão ou ficheiros de cache incorrectos. Execute a checklist de publicação.
  • Validador Qt 6 falha: enum antigo ou import directo de PyQt5. Use enums scoped e qgis.PyQt.
  • Processo externo não cancela: subprocesso executado sem polling. Mantenha referência ao processo, use timeout e force a paragem apenas quando necessário.
  • Resultados inconsistentes: estados ausentes ou excepções agregadas numa mensagem genérica. Registe uma linha de resultado por ficheiro e subcamada.
  • Camada não recebe campos: provider não suporta alteração ou camada está em estado incompatível. Verifique capacidades e actualize os campos.
  • Erro só em determinados projectos: CRS inválido, camada corrompida, geometria diferente ou definições persistentes antigas. Registe o contexto e teste com projecto vazio.

8.4 31. Checklists

8.4.1 31.1 Antes de desenvolver

8.4.2 31.2 Antes de criar PR

8.4.3 31.3 Antes de publicar

8.5 32. Próximos níveis

Depois de dominar estes padrões, explore:

  • Processing providers e algoritmos personalizados;
  • QGIS Server plugins;
  • formulários e widgets de edição;
  • layouts e relatórios;
  • integração com bases PostGIS;
  • autenticação do QGIS;
  • modelos de dados e validação de topologia;
  • testes em containers QGIS;
  • qgis-plugin-ci;
  • publicação de documentação com MkDocs ou Sphinx.

A evolução deve ser guiada por problemas reais, não por uma lista de funcionalidades. Os dois plugins estudados tornaram-se mais fortes quando cada versão respondeu a falhas observadas: lentidão, falta de auditoria, incompatibilidade Qt 6, snapping, diagnósticos de rede, validação de segurança e publicação reproduzível.