Important
La traduction est le fruit d’un effort communautaire auquel vous pouvez vous joindre. Cette page est actuellement traduite à 96.08%.
1. Standards de développement 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. Classes
1.1.1. Fonctions d’accesseurs
Assurez-vous que les accesseurs sont correctement marqués avec const
. Le cas échéant, cela peut nécessiter que les variables membres du type de valeur en cache soient marquées avec mutable
.
1.1.2. Arguments de la fonction
Portez une attention particulière à quand les arguments devraient être passés par référence. À moins que les objets argument soient petits et trivialement copiés (tels que les objets QPoint), ils doivent être passés par une référence const. Par souci de cohérence avec l’API Qt, même les objets partagés implicitement sont passés par une référence const (p. ex. setTitle( const QString& title )
au lieu de setTitle( QString title )
.
1.1.3. Valeurs de retour de la fonction
Renvoie les objets petits et trivialement copiés en tant que valeurs. Les objets plus grands doivent être renvoyés par une référence const. La seule exception à cela porte sur les objets implicitement partagés, qui sont toujours renvoyés par valeur. Renvoie QObject
ou les objets sous-classes en tant que pointeurs.
int maximumValue() const
const LayerSet& layers() const
QString title() const
(QString
est implicitement partagée)QList< QgsMapLayer* > layers() const
(QList
est implicitement partagé)QgsVectorLayer *layer() const;
(QgsVectorLayer
hérite deQObject
)QgsAbstractGeometry *geometry() const;
(QgsAbstractGeometry
est abastrait et nécessitera probablement d’être typé)
1.2. Documentation de l’API
Il est requis d’écrire la documentation API pour chaque classe, méthode, enumération et autres codes disponible dans l’API publique.
QGIS utilise Doxygen pour la documentation. Rédigez des commentaires descriptifs et significatifs qui donnent au lecteur des informations sur ce à quoi il doit s’attendre, sur ce qui se passe dans les cas limites et lui donnent des indications sur d’autres interfaces qu’il pourrait rechercher, sur les meilleures pratiques et sur des échantillons de code.
1.2.1. Variables membres
Les variables membres devraient normalement être dans la section private
et rendues accessibles via les getters et les setters. Une exception à cela existe pour les conteneurs de données comme pour la remontée d’erreurs. Dans ces cas, ne préfixez pas les membres par un m
.
1.3. Qt Designer
1.3.1. Les classes générées
Les classes QGIS générées depuis des fichiers Qt Designer (.ui) doivent avoir comme suffixe -Base. Cela permet d’identifier la classe comme étant une classe générée.
Exemples:
QgsPluginManagerBase
QgsUserOptionsBase
1.3.2. Dialogues
Toutes les boîtes de dialogue doivent intégrer des info-bulles d’aide pour toutes les icônes de la barre d’outils ainsi que pour les autres widgets appropriés. Ces info-bulles apportent beaucoup à la découverte des fonctionnalités pour les utilisateurs débutants et confirmés.
Assurez-vous que l’ordre des onglets pour les widgets est bien mis à jour à chaque fois que la boîte de dialogue de la couche change.
1.4. Fichiers C++
1.4.1. En-tête standard et licence
Chaque fichier source doit contenir une en-tête calquée sur l’exemple qui suit:
/***************************************************************************
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.
*
***************************************************************************/
Note
Il existe un modèle pour Qt Creator dans le dépôt Git. Pour l’utiliser, copiez-le depuis qt_creator_license_template vers un emplacement local, adaptez l’adresse de courrier électronique et, si requis, le nom du développeur et configurez Qt Creator pour utiliser ce modèle : .
1.5. Edition
N’importe quel éditeur ou EDI peut être utilisé pour éditer le code de QGIS, sous réserve qu’il respecte les pré-requis suivants:
1.5.1. Tabulations
Paramétrez votre éditeur pour remplacer les tabulations par des espaces. L’espacement d’une tabulation doit être paramétrée pour occuper deux espaces.
Note
Sous Vim, vous pouvez utiliser set expandtab ts=2
1.5.2. Indentation
Le code source doit être indenté pour améliorer la lisibilité. Le fichier prepare_commit.sh vérifie les fichiers modifiés et les ré-indente en utilisant l’utilitaire astyle. Il devrait être lancé avant de commiter. Vous pouvez également utiliser le script astyle.sh pour indenter des fichiers individuellement.
Les nouvelles version de astyle indentent différemment que la version utilisée pour ré-indenter l’intégralité des sources, nous avons inclus une veille version du script astyle dans notre dépôt (activez la variable WITH_ASTYLE
dans le cmake pour l’inclure dans votre build).
1.6. Compatibilité API
Il y a la Documentation de l’API pour C ++.
Nous essayons de conserver l’API stable et rétrocompatible. Les remises à niveau de l’API doivent être réalisées d’une manière similaire au code source de Qt, par ex.
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. Liaisons SIP
Certain fichiers SIP sont automatiquement générés en utilisant un script dédié.
1.7.1. Pré-traitement d’en-tête
Toutes les informations pour construire proprement le fichier SIP doivent être présentes dans le fichier d’en-tête C++. Quelques macros sont disponibles pour ces définitions:
Utilisez
#ifdef SIP_RUN
pour générer du code uniquement dans les fichiers SIP ou#ifndef SIP_RUN
pour le code C ++ uniquement. Les instructions#else
sont gérées dans les deux cas.Utilisez
SIP_SKIP
pour sauter une ligneLes annotations suivante sont traitées:
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/
Les sections
private
ne sont pas affichées, sauf si vous utilisez une instruction#ifdef SIP_RUN
dans ce bloc.SIP_PYDEFAULTVALUE(valeur)
peut être utilisé pour définir une valeur par défaut alternative à la méthode par python. Si la valeur par défaut contient une virgule,
, la valeur doit être entourée par des simples guillements'
.SIP_PYTYPE(type)
peut-être utilisé pour définir une type alternatif d’un argument à la méthode par python. Si le type contient une virgule,
, le type doit être entouré de simples guillemets'
.
Un fichier de démo, sipifyheader.h, est également disponible.
1.7.2. Générer le fichier SIP
Le fichier SIP peut être généré en utilisant un script dédié. Par exemple :
scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip
Pour générer automatiquement le fichier SIP d’un fichier C++ nouvellement ajouté, le fichier sip_include.sh doit être exécuté.
As soon as a SIP file is added to one of the source file (core_auto.sip, gui_auto.sip or analysis_auto.sip), it will be considered as generated automatically. A test will ensure that this file is up to date with its corresponding header.
Pour forcer la recréation des fichiers SIP, sipify_all.sh doit être exécuté.
1.7.3. Améliorer le 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. Préférences
Le code de QGIS offre un mécanisme de déclaration, d’enregistrement et d’utilisation des préférences.
Les préférences devraient être définies à l’aide d’une des implémentations disponibles (QgsSettingsEntryString, QgsSettingsEntryInteger, …).
Les préférences doivent être intégrées dans l’arborescence des paramètres (QgsSettingsTree), action qui est automatiquement effectuée lorsque vous utilisez le constructeur avec un nœud parent (QgsSettingsTreeNode).
Elles sont déclarées en
const static
, soit dans une classe dédiée, soit dans le registre directement (core, gui, app, …).la clé du paramètre devrait être dans un style
kebab-case
.
1.9. Style de code
Voici quelques trucs et astuces de programmation qui, nous l’espérons, vous aideront à réduire les erreurs, le temps de développement et la maintenance.
1.9.1. Lorsque c’est possible, utiliser du code générique
Si vous copiez-collez du code, ou si vous écrivez la même chose plusieurs fois, pensez à consolider le code en une seule fonction.
Cela permettra:
Autorisez les changements à s’effectuer à un seul endroit plutôt qu’en de multiples emplacements.
de prévenir le code pourri
de rendre plus difficile l’évolution différenciée de plusieurs copies au fil du temps, phénomène qui rend plus difficile la compréhension et la maintenance pour les autres développeurs
1.9.2. Placer les commandes sur des lignes séparées
Lors de la lecture du code il est facile de rater des commandes, si elles ne sont pas en début de ligne. Lors d’une lecture rapide, il est courant de sauter des lignes si elles ne semblent pas correspondre avec ce que l’on cherche dans les premiers caractères. Il est aussi commun de s’attendre à une commande après un conditionnel comme if
.
Considérez ceci:
if (foo) bar();
baz(); bar();
Il est très facile de rater des extraits dans le flux de contrôle. Au lieu de cela, utiliser
if (foo)
bar();
baz();
bar();
1.9.3. Recommandation de lecture
Effective Modern C++, Scott Meyers
More Effective C++, Scott Meyers
Effective STL, Scott Meyers
Design Patterns, GoF
You should also really read this article from Qt Quarterly on designing Qt style (APIs)
1.10. Crédits pour les contributions
Les contributeurs aux nouvelles fonctionnalités sont encouragés à faire connaître aux gens leur contribution via:
l’ajout d’une note au fichier de changement lors de la première incorporation du code auquel ils ont contribué, du type:
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
Ajout de leur nom à: