Questi standard dovrebbero essere seguiti da tutti gli sviluppatori di QGIS.
In QGIS le classi cominciano con Qgs e sono formate utilizzando la notazione a cammello.
Esempi:
I nomi dei membri della classe cominciano con il carattere minuscolo m e sono formati utilizzando caratteri minuscoli e maiuscoli.
Tutti i membri della classe dovrebbero essere privati. Le classi pubbliche sono FORTEMENTE scoraggiate. I membri protetti devono essere evitati quando è necessario accedere ai membri mediante l’utilizzo di sottoclassi di Python, poiché i membri protetti non possono essere utilizzati dai collegamenti Python.
Mutable static class member names should begin with a lower case s, but constant static class member names should be all caps:
I valori dei membri di classe dovrebbero essere ottenuti attraverso le funzioni di accesso. L’uso del prefisso get nel nome della funzione dovrebbe essere evitato. Le funzioni di accesso per i due membri privati di cui sopra sarebbero:
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``
I nomi delle funzioni che iniziano con la lettera in minuscolo e sono composti da lettere minuscole e maiuscole. Il nome della funzione dovrebbe comunicare qualcosa in riferimento alla funzione.
In coerenza con le API di QGIS esistenti e con le API di QT dovrebbero essere evitate le abbreviazioni. Ad esempio: setDestinationSize e non setDestSize, setMaximumValue e non setMaxVal.
Anche gli acronimi, coerentemente, dovrebbero seguire la notazione a cammello. Ad esempio setXml e non setXML.
Function arguments should use descriptive names. Do not use single letter argments (e.g. setColor( const QColor& color ) instead of setColor( const QColor& c )).
Pay careful attention to when arguments should be passed by reference. Unless argument objects are small and trivially copied (such as QPoint objects), they should be passed by const reference. For consistency with the Qt API, even implicitly shared objects are passed by const reference (e.g. setTitle( const QString& title ) instead of setTitle( QString title ).
Return small and trivially copied objects as values. Larger objects should be returned by const reference. The one exception to this is implicitly shared objects, which are always returned by value.
QGIS classes that are generated from Qt Designer (ui) files should have a Base suffix. This identifies the class as a generated base class.
Esempi:
All dialogs should implement tooltip help for all toolbar icons and other relevant widgets. Tooltips add greatly to feature discoverability for both new and experienced users.
Ensure that the tab order for widgets is updated whenever the layout of a dialog changes.
C++ implementation and header files should have a .cpp and .h extension respectively. Filename should be all lowercase and, in the case of classes, match the class name.
Example: Class QgsFeatureAttribute source files are qgsfeatureattribute.cpp and qgsfeatureattribute.h
Nota
In case it is not clear from the statement above, for a filename to match a class name it implicitly means that each class should be declared and implemented in its own file. This makes it much easier for newcomers to identify where the code is relating to specific class.
Each source file should contain a header section patterned after the following example:
/***************************************************************************
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
There is a template for Qt Creator in git. To use it, copy it from doc/qt_creator_license_template to a local location, adjust the mail address and - if required - the name and configure QtCreator to use it: Tools ‣ Options ‣ C++ ‣ File Naming.
Local variable names begin with a lower case letter and are formed using mixed case. Do not use prefixes like my or the.
Esempi:
Enumerated types should be named in CamelCase with a leading capital e.g.:
enum UnitType
{
Meters,
Feet,
Degrees,
UnknownUnit
};
Do not use generic type names that will conflict with other types. e.g. use UnkownUnit rather than Unknown
Global constants and macros should be written in upper case underscore separated e.g.:
const long GEOCRS_ID = 3344;
All signal/slot connects should be made using the “new style” connects available in Qt5. Futher information on this requirement is available in QEP #77.
Avoid use of Qt auto connect slots (i.e. those named void on_mSpinBox_valueChanged). Auto connect slots are fragile and prone to breakage without warning if dialogs are refactored.
Any text editor/IDE can be used to edit QGIS code, providing the following requirements are met.
Set your editor to emulate tabs with spaces. Tab spacing should be set to 2 spaces.
Nota
In vim this is done with set expandtab ts=2
Source code should be indented to improve readability. There is a scripts/prepare-commit.sh that looks up the changed files and reindents them using astyle. This should be run before committing. You can also use scripts/astyle.sh to indent individual files.
As newer versions of astyle indent differently than the version used to do a complete reindentation of the source, the script uses an old astyle version, that we include in our repository (enable WITH_ASTYLE in cmake to include it in the build).
There is API documentation for C++.
We try to keep the API stable and backwards compatible. Cleanups to the API should be done in a manner similar to the Qt sourcecode e.g.
class Foo
{
public:
/** This method will be deprecated, you are encouraged to use
* doSomethingBetter() rather.
* @deprecated 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();
}
Here are described some programming hints and tips that will hopefully reduce errors, development time and maintenance.
If you are cut-n-pasting code, or otherwise writing the same thing more than once, consider consolidating the code into a single function.
This will:
Prefer to put constants first in predicates.
0 == value e non value == 0
This will help prevent programmers from accidentally using = when they meant to use ==, which can introduce very subtle logic bugs. The compiler will generate an error if you accidentally use = instead of == for comparisons since constants inherently cannot be assigned values.
Adding spaces between operators, statements, and functions makes it easier for humans to parse code.
Which is easier to read, this:
if (!a&&b)
o questo:
if ( ! a && b )
Nota
scripts/prepare-commit.sh will take care of this.
When reading code it’s easy to miss commands, if they are not at the beginning of the line. When quickly reading through code, it’s common to skip lines if they don’t look like what you are looking for in the first few characters. It’s also common to expect a command after a conditional like if.
Consider:
if (foo) bar();
baz(); bar();
It’s very easy to miss part of what the flow of control. Instead use
if (foo)
bar();
baz();
bar();
Access modifiers structure a class into sections of public API, protected API and private API. Access modifiers themselves group the code into this structure. Indent the access modifier and declarations.
class QgsStructure
{
public:
/**
* Constructor
*/
explicit QgsStructure();
}
You should also really read this article from Qt Quarterly on designing Qt style (APIs)
Contributors of new functions are encouraged to let people know about their contribution by:
adding a note to the changelog for the first version where the code has been incorporated, of the type:
This feature was funded by: Olmiomland http://olmiomland.ol
This feature was developed by: Chuck Norris http://chucknorris.kr
writing an article about the new feature on a blog, and add it to the QGIS planet http://plugins.qgis.org/planet/
adding their name to: