Importante

unireLa traduzione è uno sforzo comunitario you can join. Questa pagina è attualmente tradotta al 97.06%.

1. Standard di programmazione QGIS

QGIS coding standards are described in the policy document available at QEP #314. All developers are required to follow those policies. Please note that QEP #314 is a live document, and that these policies may change over time.

1.1. Classi

1.1.1. Funzioni di Accesso

Assicurati che gli accessori siano definiti correttamente con const. Quando appropriato, ciò potrebbe richiedere che le variabili membro del tipo di valore memorizzato nella cache siano contrassegnate con mutable

1.1.2. Argomenti della Funzione

Presta molta attenzione a quando gli argomenti devono essere passati per riferimento. A meno che gli oggetti argomento non siano piccoli e banalmente copiati (come gli oggetti QPoint), dovrebbero essere passati per riferimento const. Per coerenza con l’API Qt, anche gli oggetti condivisi implicitamente vengono passati tramite riferimento const (ad esempio setTitle (const QString&title)” invece di setTitle (QString title).

1.1.3. Valori di Ritorno della Funzione

Restituisce oggetti piccoli e banalmente copiati come valori. Gli oggetti più grandi dovrebbero essere restituiti dal riferimento const. L’unica eccezione a ciò sono gli oggetti condivisi implicitamente, che vengono sempre restituiti per valore. Restituisce QObject” o oggetti sottoclasse come puntatori.

  • int maximumValue() const

  • const LayerSet& layers() const

  • QString title() const (QString è implicitamente condiviso)

  • QList< QgsMapLayer* > layers() const (QList` è implicitamente condiviso)

  • QgsVectorLayer *layer() const; (QgsVectorLayer eredita QObject)

  • QgsAbstractGeometry *geometry() const; (QgsAbstractGeometry è astratto e probabilmente dovrà essere trasformato)

1.2. Documentazione API

È necessario scrivere documentazione API per ogni class, method, enum ed altro codice disponibile nelle API pubbliche.

QGIS utilizza Doxygen per la documentazione. Scrivi commenti descrittivi e significativi che diano al lettore informazioni su cosa aspettarsi, cosa succede nei casi limite e diano suggerimenti su altre interfacce che potrebbe cercare, sulle migliori pratiche e sugli esempi di codice.

1.2.1. Membri Variabili

Le variabili membro dovrebbero normalmente essere nella sezione private e rese disponibili tramite getter e setter. Un’eccezione a questo è per i contenitori di dati come per la segnalazione degli errori. In questi casi non anteporre al membro una m.

1.3. Qt Designer

1.3.1. Classi Generate

Le classi QGIS generate da file Qt Designer (ui) dovrebbero avere un suffisso Base. Ciò identifica la classe come una classe base generata.

Esempi:

  • QgsPluginManagerBase

  • QgsUserOptionsBase

1.3.2. Finestre di dialogo

Tutte le finestre di dialogo dovrebbero implementare l’aiuto Tooltip per tutte le icone della barra degli strumenti e altri widget rilevanti. I tooltip aggiungono notevole efficacia alla funzionalità di reperibilità per i utenti nuovi ed esperti.

Assicurarsi che l’ordine della scheda per i widget venga aggiornato ogni volta che il layout di una finestra di dialogo cambia.

1.4. File C++

1.4.1. Intestazione Standard e Licenza

Ogni file sorgente dovrebbe contenere una sezione di intestazione modellata dopo il seguente esempio:

/***************************************************************************
  qgsfield.cpp - Describes a field in a layer or table
  --------------------------------------
  Date : 01-Jan-2004
  Copyright: (C) 2004 by Gary E.Sherman
  Email: sherman at mrcc.com
/***************************************************************************
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 ***************************************************************************/

Nota

C’è un modello per Qt Creator nel repository git. Per usarlo, copialo da qt_creator_license_template in una posizione locale, imposta l’indirizzo di posta e, se necessario, il nome e configura QtCreator per usarlo: Tools ► Options ► C++ ► File Naming.

1.5. Modifica

Qualsiasi editor di testo/IDE può essere usato per modificare il codice QGIS, a condizione che siano soddisfatti i seguenti requisiti.

1.5.1. Schede

Imposta il tuo editor per emulare le tabulazioni con gli spazi. La spaziatura delle tabulazioni dovrebbe essere impostata a 2 spazi.

Nota

In vim questo viene fatto con set expandtab ts=2.

1.5.2. Indentazione

Il codice sorgente dovrebbe essere indentato per migliorare la leggibilità. Esiste un file prepare_commit.sh che cerca i file modificati e li reindenta usando astyle. Dovrebbe essere eseguito prima del commit. Si può anche usare astyle.sh per indentare i singoli file.

Poiché le nuove versioni di astyle indentano in modo diverso rispetto alla versione usata per fare una reindentazione completa del sorgente, lo script usa una vecchia versione di astyle, che includiamo nel nostro repository (abilitando WITH_ASTYLE in cmake per includerla nella compilazione).

1.6. Compatibilità API

C’è Documentazione API per C++.

Cerchiamo di mantenere l’API stabile e compatibile con le versioni precedenti. Le revisioni dell’API dovrebbero essere fatte in modo simile al codice sorgente di Qt, ad esempio.

class Foo
{
  public:
    /**
     * This method will be deprecated, you are encouraged to use
     * doSomethingBetter() rather.
     * \deprecated use doSomethingBetter()
     */
    Q_DECL_DEPRECATED bool doSomething();

    /**
     * Does something a better way.
     * \note added in 1.1
     */
    bool doSomethingBetter();

  signals:
    /**
     * This signal will be deprecated, you are encouraged to
     * connect to somethingHappenedBetter() rather.
     * \deprecated use somethingHappenedBetter()
     */
#ifndef Q_MOC_RUN
    Q_DECL_DEPRECATED
#endif
    bool somethingHappened();

    /**
     * Something happened
     * \note added in 1.1
     */
    bool somethingHappenedBetter();
}

1.7. Collegamenti SIP

Alcuni dei file SIP sono generati automaticamente utilizzando uno script dedicato.

1.7.1. Pre-elaborazione intestazione

Tutte le informazioni per costruire correttamente il file SIP devono essere contenute nel file C++i intestazione . Sono disponibili alcune macro per tale definizione:

  • Usa #ifdef SIP_RUN per generare codice solo nei file SIP o #ifndef SIP_RUN per il solo codice C++. Le istruzioni #else vengono gestite in entrambi i casi.

  • Usa SIP_SKIP per cancellare una linea

  • Le annotazioni che seguono sono gestite:

    • SIP_FACTORY: /Factory/

    • SIP_OUT: /Out/

    • SIP_INOUT: /In,Out/

    • SIP_TRANSFER: /Transfer/

    • SIP_PYNAME(name): /PyName=name/

    • SIP_KEEPREFERENCE: /KeepReference/

    • SIP_TRANSFERTHIS: /TransferThis/

    • SIP_TRANSFERBACK: /TransferBack/

  • le sezioni private non vengono visualizzate, a meno di usare, in questo blocco, il comando #ifdef SIP_RUN

  • SIP_PYDEFAULTVALUE(value) può essere usato per definire un valore predefinito alternativo del metodo python. Se il valore predefinito contiene una virgola ,, il valore deve essere racchiuso tra apici singoli '.

  • SIP_PYTYPE(tipo) può essere usato per definire un tipo alternativo per un argomento del metodo python. Se il tipo contiene una virgola ,, il tipo deve essere racchiuso tra apici singoli '.

È disponibile anche un file di esempio, sipifyheader.h.

1.7.2. Generazione del file SIP

Il file SIP può essere generato utilizzando uno script dedicato. Ad esempio:

scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip

Per generare automaticamente il file SIP di un nuovo file C++ aggiunto è necessario eseguire sip_include.sh.

Non appena un file SIP viene aggiunto a uno dei file sorgente (core_auto.sip, gui_auto.sip o analysis_auto.sip), sarà considerato come generato automaticamente. Un test assicurerà che questo file sia aggiornato con la sua intestazione corrispondente.

Per forzare la ricreazione dei file SIP, deve essere eseguito sipify_all.sh.

1.7.3. Miglioramento dello script sipify

If some improvements are required for sipify script, please add the missing bits to the demo file sipifyheader.h and create the expected header sipifyheader.expected.sip file. This will also be automatically tested as a unit test of the script itself.

1.8. Impostazioni

Il codice di base di QGIS offre un meccanismo per dichiarare, registrare e utilizzare le impostazioni.

  • le impostazioni devono essere create utilizzando una delle implementazioni disponibili (QgsSettingsEntryString, QgsSettingsEntryInteger, …).

  • le impostazioni devono essere integrate nell’albero delle impostazioni (QgsSettingsTree), questo viene fatto automaticamente quando si usa il costruttore con un nodo padre (QgsSettingsTreeNode).

  • sono dichiarati come const static o in una classe dedicata o direttamente nel registro (core, gui, app, …).

  • la funzione di impostazione dovrebbe utilizzare un kebab-case.

1.9. Stile Programmazione

Qui sono descritti alcuni suggerimenti e consigli di programmazione che permetteranno di ridurre gli errori, i tempi di sviluppo e la manutenzione.

1.9.1. Dove possibile generalizza il codice

Se fai un taglia-incolla di codice, o comunque scrivi la stessa cosa più di una volta, prendi in considerazione la possibilità di consolidare il codice in un’unica funzione.

In questo modo:

  • consente di effettuare cambiamenti in una location invece che in molte

  • eviti il gonfiamento del codice

  • rende più difficile alle copie multiple di avere differenze nel tempo , così da renderne più difficile per altri la comprensione

1.9.2. Metti i comandi su linee separate

Quando si legge il codice è facile perdere i comandi, se non si trovano all’inizio della riga. Quando si legge velocemente il codice, è comune saltare le righe se non sembrano quelle che si stanno cercando nei primi caratteri. È anche comune aspettarsi un comando dopo una condizione come if.

Considera:

if (foo) bar();

baz(); bar();

È molto facile perdere parte del controllo del flusso. Utilizza invece

if (foo)
  bar();

baz();
bar();

1.9.3. Consigli per i libri

Dovresti anche leggere questo articolo di Qt Quarterly su designing Qt style (APIs)

1.10. Crediti per contributi

Chi contribuisce a nuove funzioni è invitato a far conoscere il proprio contributo: