Outdated version of the documentation. Find the latest one here.

Standardele de codificare QGIS

Aceste standarde ar trebui să fie urmate de către toți dezvoltatorii QGIS.

Clase

Nume

Clasele din QGIS sunt prefixate cu Qgs, iar fiecare cuvânt începe cu majusculă.

Exemple:

  • QgsPoint
  • QgsMapCanvas
  • QgsRasterLayer

Membri

Denumirile membrilor claselor sunt prefixate cu litera m și sunt formate utilizând majuscule și minuscule.

  • mMapCanvas
  • mCurrentExtent

Toți membrii claselor ar trebui să fie privați. Membrii publici sunt TOTAL nerecomandați. Membrii protejați ar trebui să fie evitați când membrul ar putea fi accesat din subclase Python, de vreme ce membrii protejați nu pot fi utilizați din legăturile Python.

Mutable static class member names should begin with a lower case s, but constant static class member names should be all caps:

  • sRefCounter
  • DEFAULT_QUEUE_SIZE

Funcțiile Accesor

Valorile membrilor unei clase vor fi obținute prin intermediul funcțiilor accesor. Numele acestora nu ar trebui să înceapă cu prefixul “get”. Funcțiile accesor pentru cei doi membri privați de mai sus ar putea fi:

  • mapCanvas()
  • currentExtent()

Asigurați-vă că accesoriile sunt corect marcate cu const. Atunci când este cazul, este posibil ca variabilele membru, de tip cache de valoare, să fie marcate cu mutable.

Funcții

Numele funcțiilor încep cu literă mică și conțin majuscule și minuscule. Numele funcțiilor ar trebui să indice scopul acestora.

  • updateMapExtent()
  • setUserOptions()

În concordanță cu API-urile QGIS și Qt, ar trebui evitate abrevierile. De exemplu: setDestinationSize în loc de setDestSize, setMaximumValue în loc de setMaxVal.

De asemenea, acronimele ar trebui să fie denumite folosind CamelCase. De exemplu: setXml în loc de setXML.

Argumente ale funcțiilor

Function arguments should use descriptive names. Do not use single letter argments (e.g. setColor( const QColor& color ) instead of setColor( const QColor& c )).

Acordați o atenție deosebită momentului când argumentele ar trebui să fie transmise prin referință. Cu excepția cazului în care obiectele argumentului nu au dimensiuni mari și sunt trivial de copiat (cum ar fi obiectele QPoint), ele ar trebui să fie transmise prin referințe constante. Pentru concordanța cu API-ul Qt, chiar și obiectele partajate în mod implicit sunt transmise prin referințe constante (ex.: setTitle( const QString& title ) în loc de setTitle( QString title ).

Valorile Returnate de Funcție

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.

  • int maximumValue() const
  • const LayerSet& layers() const
  • QString title() const (QString is implicitly shared)
  • QList< QgsMapLayer* > layers() const (QList is implicitly shared)

Qt Designer

Clasele Generate

Clasele QGIS care sunt generate în fișierele produse de Qt Designer (UI) ar trebui să aibă sufixul Base. Acest lucru identifică o clasă de bază, generată.

Exemple:

  • QgsPluginManagerBase
  • QgsUserOptionsBase

Dialoguri

Toate dialogurile ar trebui să implementeze ajutorul pentru toate pictogramele barei de instrumente și alte controale grafice relevante. Baloanele cu indicii adaugă foarte mult la descoperirea caracteristicilor, atât pentru utilizatorii noi, cât și pentru cei experimentați.

Asigurați-vă că ordinea filelor pentru controalele grafice este actualizată ori de câte ori se modifică aspectul unui dialog.

Fișierele C++

Nume

Fișierele antet și de implementare C++ ar trebui să aibă extensiile .h, respectiv .cpp. Numele de fișier ar trebui să conțină doar litere mici și, în cazul claselor, să se potrivească numelui clasei.

Example: Class QgsFeatureAttribute source files are qgsfeatureattribute.cpp and qgsfeatureattribute.h

Note

În cazul în care nu este clară indicația de mai sus, cerința ca numele de fișier să se potrivească numelui de clasă, arată că, implicit, fiecare clasă trebuie să fie declarată și implementată în propriul fișier. Acest lucru facilitează nou-veniților identificarea codului care este specific anumitor clase.

Antetul Standard și Licența

Fiecare fișier sursă trebuie să conțină o secțiune antet, în conformitate cu exemplul următor:

/***************************************************************************
  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

Există un șablon pentru Qt Creator în git. Pentru a-l utiliza, copiați-l din doc/qt_creator_license_template într-un dosar local, ajustați adresa e-mail și numele - dacă este necesar - apoi configurați QtCreator pentru a-l folosi: Instrumente ‣ Opțiuni ‣ C++ ‣ Denumirea Fișierului.

Numele Variabilei

Numele variabilelor locale încep cu o literă mică, utilizând majuscule și minuscule. Nu folosiți prefixe precum my sau the.

Exemple:

  • mapCanvas
  • currentExtent

Tipurile Enumerate

Tipurile enumerate ar trebui să fie denumite folosind CamelCase, începând cu o majusculă, de ex.:

enum UnitType
{
  Meters,
  Feet,
  Degrees,
  UnknownUnit
};

Nu utilizați tipuri de nume generice, care vor intra în conflict cu alte tipuri. De ex., folosiți mai degrabă UnkownUnit decât Unknown

Constantele locale și Comenzile Macro

Constantele locale și comenzile macro ar trebui să fie scrise cu majuscule, separate cu ajutorul caracterului de subliniere, de ex .:

const long GEOCRS_ID = 3344;

Semnale și Sloturi Qt

Toate conexiunile la semnale/sloturi ar trebui să fie făcute folosindu-se legăturile de “stil nou” disponibile în Qt5. Informații suplimentare privind această cerință sunt disponibile în QEP #77.

Evitați folosirea sloturilor cu autoconectare QT (adică pe acelea denumite void on_mSpinBox_valueChanged). Sloturile cu autoconectare sunt fragile și predispuse la întrerupere, fără avertisment, dacă dialogurile sunt refactorizate.

Editarea

Orice editor de text/IDE poate fi folosit pentru a edita codul QGIS, oferind garanția că sunt îndeplinite următoarele cerințe.

Caracterele TAB

Setați în editorul dvs. emularea TAB-ului cu ajutotul spațiilor albe. Ar trebui folosite în acest scop 2 spații.

Note

În vim, acest lucru se realizează prin comanda set expandtab ts=2

Indentarea

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).

Acoladele

Acoladele ar trebui să fie poziționate pe linia următoare expresiei:

if(foo == 1)
{
  // do stuff
  ...
}
else
{
  // do something else
  ...
}

Compatibilitatea API-ului

There is API documentation for C++.

Încercăm să păstrăm API-ul stabil și compatibil cu versiunile anterioare. Curățarea API-ului ar trebui să fie făcută într-un mod similar cu al codului sursă Qt, de ex.:

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();
}

Stilul de Codificare

Aici sunt descrise câteva sugestii și sfaturi de programare care vor reduce, sperăm, erorile, timpul de întreținere și dezvoltare.

Generalizați Codul Atunci Când Este Posibil

Decât să duplicați un anumit cod, mai bine luați în considerare consolidarea acestuia într-o funcție unică.

Acest lucru vă va permite să:

  • efectuați modificări într-o singură locație în loc de mai multe

  • preveniți încurcarea codului

  • împiedica apariția, de-a lungul timpului, a diferențelor între secțiunile identice de cod, făcându-le, astfel, mai greu de înțeles și de întreținut de către alții

Se preferă poziționarea Constantelor înaintea Predicatelor

Se preferă poziționarea constantelor la începutul predicatelor.

0 == value în loc de value == 0

Acest lucru va ajuta prevenirea folosirii accidentale de = în loc de ==, care poate introduce erori subtile de logică. Compilatorul va genera o eroare dacă folosiți accidental = în loc de == pentru comparații, deoarece nu se pot atribui valori constantelor.

Spațiile Albe Vă Pot Fi De Ajutor

Adăugarea de spații între operatori, declarații și funcții, facilitează utilizatorilor analiza codului.

Care cod este mai ușor de citit? Acesta:

if (!a&&b)

sau acesta:

if ( ! a && b )

Note

scripts/prepare-commit.sh will take care of this.

Puneți comenzile pe linii separate

La citirea codului, este ușor să omiteți comenzile dacă acestea nu se află la începutul liniei. La parcurgerea rapidă a codului, este normal să omiteți liniile atunci când acestea nu prezintă ceea ce căutați în primele câteva caractere. Este, de asemenea, normal să vă așteptați la o comandă după un condițional ca if.

Se ia în considerare următorul cod:

if (foo) bar();

baz(); bar();

Este foarte ușor să omiteți o parte din fluxul de control. Scrieți, în schimb

if (foo)
  bar();

baz();
bar();

Indentați modificatorii de acces

Modificatorii de acces structurează o clasă în secțiuni de API public, API protejat și API privat. Rolul lor este de a grupa codul pe această structură. Indentați modificatorii de acces și declarațiile.

class QgsStructure
{
  public:
    /**
     * Constructor
     */
     explicit QgsStructure();
}

Cărți recomandate

Ar trebui, de asemenea, să citiți acest articol de la Qt Quarterly despre proiectarea în stilul Qt (API)

Recunoașterea contribuțiilor

Contribuitorii la noile funcții sunt încurajați să-i informeze pe ceilalți despre contribuția lor prin: