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
ereditaQObject
)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: .
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 lineaLe 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
Effective Modern C++, Scott Meyers
More Effective C++, Scott Meyers
Effective STL, Scott Meyers
Design Patterns, GoF
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:
aggiungendo una nota al changelog della prima versione in cui il codice è stato incorporato, del tipo:
This feature was funded by: Olmiomland https://olmiomland.ol This feature was developed by: Chuck Norris https://chucknorris.kr
writing an article about the new feature on a blog, and add it to QGIS Planet
aggiungendo il proprio nome: