Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.
1. QGIS kodningsstandarder
QGIS kodningsstandarder beskrivs i policydokumentet som finns tillgängligt på QEP #314. Alla utvecklare är skyldiga att följa dessa policyer. Observera att QEP #314 är ett aktuellt dokument och att dessa policyer kan komma att ändras över tid.
1.1. Klasser
1.1.1. Accessorfunktioner
Se till att accessorer är korrekt markerade med const
. I förekommande fall kan detta kräva att medlemsvariabler av typen cached value markeras med mutable
.
1.1.2. Funktion Arguments
Var noga med när argument ska skickas med referens. Om inte argumentobjekten är små och trivialt kopierade (t.ex. QPoint-objekt) bör de skickas med const-referens. För att vara konsekvent med Qt API, skickas även implicit delade objekt med const-referens (t.ex. setTitle( const QString& title )
istället för setTitle( QString title )
.
1.1.3. Funktion Returvärden
Returnera små och trivialt kopierade objekt som värden. Större objekt bör returneras med const-referens. Det enda undantaget från detta är implicit delade objekt, som alltid returneras som värde. Returnera QObject
eller underklassade objekt som pekare.
int maximumValue() const
const LayerSet& layers() const
QString title() const
(QString
är implicit delad)QList< QgsMapLayer* > layers() const
(QList
är implicit delad)QgsVectorLayer *layer() const;
(QgsVectorLayer
ärverQObject
)QgsAbstractGeometry *geometry() const;
(QgsAbstractGeometry
är abstrakt och kommer förmodligen att behöva castas)
1.2. API-dokumentation
Det är obligatoriskt att skriva API-dokumentation för varje klass, metod, enum och annan kod som finns tillgänglig i det publika API:et.
QGIS använder Doxygen för dokumentation. Skriv beskrivande och meningsfulla kommentarer som ger läsaren information om vad han eller hon kan förvänta sig, vad som händer i undantagsfall och ger tips om andra gränssnitt som han eller hon kan leta efter, bästa praxis och kodexempel.
1.2.1. Medlemmar Variabler
Medlemsvariabler ska normalt ligga i avsnittet private
och göras tillgängliga via getters och setters. Ett undantag från detta är för datacontainrar som för felrapportering. I sådana fall ska man inte prefixera medlemmen med ett m
.
1.3. Qt Designer
1.3.1. Genererade klasser
QGIS-klasser som genereras från Qt Designer (ui)-filer bör ha ett Base-suffix. Detta identifierar klassen som en genererad basklass.
Exempel:
QgsPluginManagerBase
QgsUserOptionsBase
1.3.2. Dialoger
Alla dialogrutor bör implementera verktygstips för alla ikoner i verktygsfältet och andra relevanta widgets. Verktygstips gör det mycket lättare för både nya och erfarna användare att hitta funktioner.
Se till att flikordningen för widgetar uppdateras när layouten för en dialog ändras.
1.4. C++-filer
1.4.1. Standardhuvud och licens
Varje källfil ska innehålla ett huvudavsnitt enligt följande exempel:
/***************************************************************************
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.
*
***************************************************************************/
Observera
Det finns en mall för Qt Creator i git-repository. För att använda den, kopiera den från qt_creator_license_template till en lokal plats, justera e-postadressen och - om så krävs - namnet och konfigurera QtCreator att använda den: .
1.5. Ändrar
Alla textredigerare/IDE kan användas för att redigera QGIS-kod, förutsatt att följande krav är uppfyllda.
1.5.1. Tabulatorer
Ställ in din editor så att den emulerar tabbar med mellanslag. Tabbavstånd bör ställas in på 2 mellanslag.
Observera
I vim görs detta med set expandtab ts=2
1.5.2. Indrag
Källkod bör vara indragen för att förbättra läsbarheten. Det finns en prepare_commit.sh-fil som letar upp de ändrade filerna och indenterar dem på nytt med hjälp av astyle. Detta bör köras innan du skickar. Du kan också använda astyle.sh för att indentera enskilda filer.
Eftersom nyare versioner av astyle indenterar på ett annat sätt än den version som används för att göra en fullständig omindentering av källan, använder skriptet en gammal astyle-version som vi inkluderar i vårt arkiv (aktivera WITH_ASTYLE
i cmake för att inkludera den i byggandet).
1.6. API-kompatibilitet
Det finns API-dokumentation för C++.
Vi försöker hålla API:et stabilt och bakåtkompatibelt. Uppstädningar av API:et bör göras på ett sätt som liknar Qt-källkoden, t.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. SIP-bindningar
Vissa av SIP-filerna genereras automatiskt med hjälp av ett särskilt skript.
1.7.1. Förbehandling av rubriker
All information för att bygga SIP-filen på rätt sätt måste finnas i C++-headerfilen. Vissa makron finns tillgängliga för sådan definition:
Använd
#ifdef SIP_RUN
för att generera kod endast i SIP-filer eller#ifndef SIP_RUN
för C++-kod endast.#else
-satser hanteras i båda fallen.Använd
SIP_SKIP
för att förkasta en radFöljande anteckningar hanteras:
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/
privata
sektioner visas inte, förutom om du använder en#ifdef SIP_RUN
-sats i detta block.SIP_PYDEFAULTVALUE(value)
kan användas för att definiera ett alternativt standardvärde för pythonmetoden. Om standardvärdet innehåller ett kommatecken,
, ska värdet omges av enkla citattecken'
SIP_PYTYPE(type)
kan användas för att definiera en alternativ typ för ett argument i pythonmetoden. Om typen innehåller ett kommatecken,
, ska typen omges av enkla citattecken'
En demofil, sipifyheader.h, finns också tillgänglig.
1.7.2. Generering av SIP-filen
SIP-filen kan genereras med hjälp av ett särskilt skript. Till exempel:
scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip
För att automatiskt generera SIP-filen för en nyligen tillagd C++-fil måste sip_include.sh köras.
Så snart en SIP-fil läggs till i en av källfilerna (core_auto.sip, gui_auto.sip eller analysis_auto.sip) kommer den att betraktas som automatiskt genererad. Ett test kommer att säkerställa att filen är uppdaterad med motsvarande header.
För att tvinga fram återskapande av SIP-filer ska sipify_all.sh köras.
1.7.3. Förbättring av sipify-skriptet
Om några förbättringar krävs för sipify-skriptet, lägg till de saknade bitarna i demofilen sipifyheader.h och skapa den förväntade rubriken sipifyheader.expected.sip
-filen. Detta kommer också att testas automatiskt som ett enhetstest av själva skriptet.
1.8. Inställningar
QGIS kodbas erbjuder en mekanism för att deklarera, registrera och använda inställningar.
inställningar bör definieras med hjälp av en av de tillgängliga implementationerna (QgsSettingsEntryString, QgsSettingsEntryInteger, …).
inställningar måste integreras i inställningsträdet (QgsSettingsTree), detta görs automatiskt när man använder konstruktorn med en överordnad nod (QgsSettingsTreeNode).
de deklareras som
const static
antingen i en särskild klass eller direkt i registret (core, gui, app, …).inställningsnyckeln bör använda ett
kebab-fodral
.
1.9. Kodningsstil
Här beskrivs några programmeringstips som förhoppningsvis kommer att minska fel, utvecklingstid och underhåll.
1.9.1. Generalisera koden där det är möjligt
Om du klipper och klistrar kod eller på annat sätt skriver samma sak mer än en gång kan du överväga att konsolidera koden till en enda funktion.
Det kommer det att göra:
göra det möjligt att göra ändringar på en plats i stället för på flera platser
hjälpa till att förhindra uppsvälld kod
göra det svårare för flera kopior att utveckla skillnader över tiden, vilket gör det svårare att förstå och underhålla för andra
1.9.2. Skriv kommandon på separata rader
När man läser kod är det lätt att missa kommandon om de inte står i början av raden. När man snabbt läser igenom kod är det vanligt att hoppa över rader om de inte ser ut som det man letar efter i de första tecknen. Det är också vanligt att man förväntar sig ett kommando efter ett villkor som if
.
Tänk på det:
if (foo) bar();
baz(); bar();
Det är mycket lätt att missa en del av vad kontrollflödet. Använd istället
if (foo)
bar();
baz();
bar();
1.9.3. Bokrekommendationer
Effective Modern C++, Scott Meyers
More Effective C++, Scott Meyers
Effective STL, Scott Meyers
Design Patterns, GoF
Du bör också verkligen läsa den här artikeln från Qt Quarterly om designing Qt style (APIs)
1.10. Tillgodoräknande av bidrag
De som bidrar med nya funktioner uppmanas att informera andra om sitt bidrag genom att göra detta:
lägga till en anteckning i ändringsloggen för den första versionen där koden har införlivats, av typen:
This feature was funded by: Olmiomland https://olmiomland.ol This feature was developed by: Chuck Norris https://chucknorris.kr
skriva en artikel om den nya funktionen på en blogg och lägga till den i QGIS Planet
lägga till sitt namn till: