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

Normas de Codificação QGIS

Estas normas devem ser seguidas por todos os programadores de QGIS

Classes

Nomes

Class in QGIS begin with Qgs and are formed using camel case.

Exemplos:

  • QgsPoint
  • QgsMapCanvas
  • QgsRasterLayer

Membros

Class member names begin with a lower case m and are formed using mixed case.

  • mMapCanvas
  • mCurrentExtent

All class members should be private. Public class members are STRONGLY discouraged. Protected members should be avoided when the member may need to be accessed from Python subclasses, since protected members cannot be used from the Python bindings.

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

Accessor Functions

Class member values should be obtained through accesssor functions. The function should be named without a get prefix. Accessor functions for the two private members above would be:

  • mapCanvas()
  • currentExtent()

Ensure that accessors are correctly marked with const. Where appropriate, this may require that cached value type member variables are marked with mutable.

Funções

Os nomes das funções começam com uma letra minúscula e são formados usando um misto de letras minúsculas e maiúsculas. O nome da função deve transmitir algo sobre o propósito da função.

  • updateMapExtent()
  • setUserOptions()

Para a consistência entre o QGIS API e o Qt API existente, as abreviaturas devem ser evitadas. Por exemplos: `` setDestinationSize`` em vez de `` setDestSize``, `` setMaximumValue`` em vez de `` setMaxVal``.

Acronyms should also be camel cased for consistency. E.g. setXml instead of setXML.

Argumentos da função

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

Function Return Values

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

Classes geradas

QGIS classes that are generated from Qt Designer (ui) files should have a Base suffix. This identifies the class as a generated base class.

Exemplos:

  • QgsPluginManagerBase
  • QgsUserOptionsBase

Diálogos

Todos os diálogos devem implementar dicas de ajuda para todos os ícones das barras de ferramentas e outros componentes relevantes. As dicas de ajuda são um grande auxílio para utilizadores novos ou experientes conhecerem as funcionalidades.

Certifique que a ordem das abas para os widgets é atualizada toda vez que a composição de uma janela mudar.

Ficheiros C++

Nomes

a implementação de C++ e os cabeçalhos dos ficheiros devem ter uma extensão .cpp e .h, respetivamente. O nome do arquivo deve ser todo em minúsculas e, no caso das classes, corresponder ao nome da classe.

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

Note

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.

Cabeçalho padrão e licença

Cada arquivo de código fonte deve conter um cabeçalho de acordo com o seguinte exemplo:

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

Há um template para o Qt Creator no git. Para use-lo, copie-no do arquivo doc/qt_creator_license_template para uma pasta local, ajuste o endereço de e-mail e - caso necessário - o nome e configure o QtCreator para usá-lo: menuselection:Tools –> Options –> C++ –> File Naming.

Nome das variáveis

Os nomes de variáveis locais começam com uma letra minúscula e são formados usando um misto de letras minúsculas e maiúsculas. Não usar prefixos como my ou the.

Exemplos:

  • mapCanvas
  • mapCanvas

Enumerated Types

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

Constantes Globais & Macros

Constantes globais e macros devem ser escritas em caixa alta e linha (_) por exemplo.:

const long GEOCRS_ID = 3344;

Sinais e Slots da Qt

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.

Editando

Qualquer editor de texto/ambiente de desenvolvimento (IDE) pode ser usado para editar códigos do QGIS, contanto que os seguintes requisitos sejam atendidos.

Separadores

Set your editor to emulate tabs with spaces. Tab spacing should be set to 2 spaces.

Note

In vim this is done with set expandtab ts=2

Indentation

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

Braces

Braces should start on the line following the expression:

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

Compatibilidade da Interface de Programação da Aplicação

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

Coding Style

Here are described some programming hints and tips that will hopefully reduce errors, development time and maintenance.

Where-ever Possible Generalize Code

If you are cut-n-pasting code, or otherwise writing the same thing more than once, consider consolidating the code into a single function.

Isto irá:

  • permitir que as alterações sejam feitas num só local em vez de em vários lugares

  • help prevent code bloat
  • make it more difficult for multiple copies to evolve differences over time, thus making it harder to understand and maintain for others

Prefer Having Constants First in Predicates

Prefer to put constants first in predicates.

0 == value em vez de 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.

Whitespace Can Be Your Friend

Adicionar espaços entre operadores, declarações e funções torna mais fácil para os humanos analisar o código.

O que é mais fácil de ler, isto:

if (!a&&b)

ou isto:

if ( ! a && b )

Note

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

Colocar os comandos em linhas separadas

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.

Considere:

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

Indent access modifiers

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

Book recommendations

You should also really read this article from Qt Quarterly on designing Qt style (APIs)

Créditos de contribuições

Os contribuidores de novas funções são encorajados a informar as pessoas sobre sua contribuição: