Belangrijk
Vertalen is een inspanning van de gemeenschap waaraan u deel kunt nemen <translation_guidelines>. Deze pagina is momenteel voor 100.00% vertaald.
1. QGIS standaarden voor coderen
Standaarden voor het coderen van QGIS wordne beschreven in het beleidsdocument dat beschikbaar is op QEP #314. Alle ontwikkelaars zijn verplicht dit beleid te volgen. Onthoud dat QEP #314 een levend document is en dat dit beleid in de tijd kan veranderen.
1.1. Klassen
1.1.1. Functies Accessor
Zorg er voor dat accessors juist zijn gemarkeerd met const
. Waar van toepassing zou dit er toe kunnen leiden dat gecachte waardentypen van variabele leden zijn gemarkeerd met mutable
.
1.1.2. Argumenten voor functies
Wees uitermate zorgvuldig als argumenten zouden moeten worden doorgegeven door middel van verwijzingen. Tenzij de objecten voor de argumenten klein zijn en eenvoudig zijn te kopiëren (zoals objecten QPoint), zouden zij moeten worden doorgegeven door middel van een verwijzing const. Voor consistentie met de API van Qt dienen zelfs impliciet gedeelde objecten te worden doorgegeven door een verwijzing const (bijv. setTitle( const QString& title )
in plaats van setTitle( QString title )
.
1.1.3. Teruggegeven waarden van functies
Geef kleine en eenvoudig eenvoudig te kopiëren objecten als waarden. Grotere objecten zouden moeten worden teruggegeven door een verwijzing const. De enige uitzondering hierop zijn de impliciet gedeelde objecten, die altijd met hun waarde worden teruggegeven. Geef QObject
of objecten van subklassen terug als pointers.
int maximumValue() const
const LayerSet& layers() const
QString title() const
(QString
is impliciet gedeeld)QList< QgsMapLayer* > layers() const
(QList
is impliciet gedeeld)QgsVectorLayer *layer() const;
(QgsVectorLayer
erftQObject
)QgsAbstractGeometry *geometry() const;
(QgsAbstractGeometry
is abstract en zal waarschijnlijk moeten worden gecast)
1.2. API-documentatie
Het is vereist om documentatie voor de API te schrijven voor elke klasse, methode, enumeratie en andere code die beschikbaar is in de publieke API.
QGIS gebruikt Doxygen voor documentatie. Schrijf beschrijvende en betekenisvolle opmerkingen die een lezer informatie geven over wat te verwachten, wat gebeurt er in randgevallen en geef hints over andere interfaces die hij zou kunnen gebruiken, goede beste werkwijzen en voorbeelden van code.
1.2.1. Variabele leden
Variabele leden zouden normaal gesproken in het gedeelte private
moeten staan en beschikbaar moeten komen via getters en setters. Één uitzondering hierop is voor data containers zoals voor het rapporteren van fouten. Gebruik in dergelijke gevallen niet het voorvoegsel m
voor het lid.
1.3. Qt Designer
1.3.1. Gegenereerde klassen
Klassen voor QGIS die worden gegenereerd uit Qt Designer (ui)-bestanden zouden een achtervoegsel Base moeten hebben. Dat identificeert de klasse als een gegenereerde basisklasse.
Voorbeelden:
QgsPluginManagerBase
QgsUserOptionsBase
1.3.2. Dialoogvensters
Alle dialoogvensters zouden helptips moeten implementeren voor alle pictogrammen van de werkbalk en andere relevante widgets. Helptips voegen een grote mate van ontdekkingsdrang toe voor zowel nieuwe als ervaren gebruikers.
Zorg er voor dat de tabvolgorde voor widgets wordt bijgewerkt, iedere keer als de lay-out van het dialoogvenster wijzigt.
1.4. C++-bestanden
1.4.1. Standaard header en licentie
Elk bronbestand zou een gedeelte header moeten hebben met een patroon als in het volgende voorbeeld:
/***************************************************************************
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.
*
***************************************************************************/
Notitie
Er staat een sjabloon voor Qt Creator in de opslagplaats van GIT. Kopieer het, om het te gebruiken, vanuit qt_creator_license_template naar een lokale locatie, pas het mailadres aan en - indien vereist - de naam en configureer QtCreator om het te gebruiken: Tools
-> Options
-> C++
-> File Naming
.
1.5. Bewerken
Elke tekstbewerker/IDE kan worden gebruikt om de code van QGIS te bewerken, vooropgesteld dat aan de volgende eisen wordt voldaan.
1.5.1. Tabs
Stel uw bewerker in om tabs te laten zien als spaties. De afstand voor de tab zou moeten zijn ingesteld op 2 spaties.
Notitie
In VIM wordt dit gedaan met set expandtab ts=2
1.5.2. Inspringen
Broncode zou moeten worden ingesprongen om de leesbaarheid te verbeteren. Er is een bestand prepare_commit.sh dat de gewijzigde bestanden ophaalt en ze opnieuw laat inspringen met astyle. Dit zou moeten worden uitgevoerd vóór het indienen. U kunt ook astyle.sh gebruiken om individuele bestanden in te laten springen.
Omdat nieuwere versies van astyle anders inspringen dan de gebruikte versie voor een volledige nieuw inspringen van de bron, gebruikt het script een oude versie van astyle, die we op hebben genomen in onze opslagplaats (schakel WITH_ASTYLE
in cmake in om het op te nemen in de build).
1.6. Compatibiliteit met de API
Er is API documentatie voor C++.
We proberen de API stabiel en achterwaarts compatibel te houden. Opschonen van de API zou op een manier moeten worden gedaan die soortgelijk is aan de broncode voor Qt bijv.
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-bindingen
Sommige van de SIP-bestanden worden automatisch gemaakt met een toegewezen script.
1.7.1. Voorverwerking header
Alle informatie om op de juiste manier het SIP-bestand te bouwen moet te vinden zijn in het C++ header-bestand. Enkele macro’s zijn beschikbaar voor een dergelijke definitie:
Gebruik
#ifdef SIP_RUN
om alleen code te maken in SIP-bestanden of#ifndef SIP_RUN
voor alleen code voor C++. Argumenten#else
worden in beide gevallen afgehandeld.Gebruik
SIP_SKIP
om een regel te negerenDe volgende annotaties worden afgehandeld:
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/
gedeelten
private
worden niet weergegeven, behalve wanneer u een argument#ifdef SIP_RUN
in dit blok gebruikt.SIP_PYDEFAULTVALUE(value)
kan worden gebruikt om een alternatieve standaard waarde van de methode van Python te definiëren. Als de standaard waarde een komma,
bevat, zou de waarde moeten worden omsloten door enkele aanhalingstekens'
SIP_PYTYPE(type)
kan worden gebruikt om een alternatieve type voor een argument van de methode van Python te definiëren. Als het type een komma,
bevat, zou het type moeten worden omsloten door enkele aanhalingstekens'
Een demo-bestand, sipifyheader.h, is ook beschikbaar.
1.7.2. Het SIP-bestand maken
Het SIP-bestand kan worden gemaakt met een toegewezen script. Bijvoorbeeld:
scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip
Om automatisch het SIP-bestand van een nieuw toegevoegd bestand in C++ te maken, moet sip_include.sh worden uitgevoerd.
Zodra een SIP-bestand is toegevoegd aan een van de bronbestanden(core_auto.sip, gui_auto.sip of analysis_auto.sip), zal het worden beschouwd als automatisch gemaakt. Een test zal er voor zorgen dat dit bestand up to date is met zijn overeenkomende header.
Voor het forceren van het opnieuw maken van SIP-bestanden zal sipify_all.sh worden uitgevoerd.
1.7.3. Verbeteren van script sipify
Als enkele verbeteringen vereist zijn voor het script sipify, voeg dan de ontbrekende gedeelten toe aan het demo-bestand sipifyheader.h en maak de verwachte headerbestand sipifyheader.expected.sip
. Dit zal ook automatisch worden getest als een eenheidstest van het script zelf.
1.8. Instellingen
De codebasis van QGIS biedt een mechanisme om instellingen te declareren, registreren en te gebruiken.
instellingen zouden moeten worden gedefinieerd met een van de beschikbare implementaties (QgsSettingsEntryString, QgsSettingsEntryInteger, …).
instellingen moeten zijn geïntegrertd in de boom met instellingen (QgsSettingsTree), dat wordt automatisch gedaan bij het gebruiken van de constructor met een ouder-node (QgsSettingsTreeNode).
zij worden gedeclareerd als
const static
, ofwel in een aangewezen klasse of direct in het register (core, gui, app, …).de sleutel voor de instelling zou een
kebab-case
moeten gebruiken.
1.9. Stijl van coderen
Hier worden enkele hints en tips beschreven voor het programmeren die hopelijk het aantal fouten, ontwikkeltijd en onderhoud reduceren.
1.9.1. Waar mogelijk: generaliseer code
Indien u code knipt-en-plakt, of op een andere manier hetzelfde meer dan eens schrijft, overweeg dan om de code te consolideren in één enkele functie.
Dat zal:
het mogelijk maken wijzigingen op één plaats door te voeren in plaats van op meerdere plaatsen
helpen bij het tegengaan van overbodige code
het moeilijker maken voor meerdere kopieën om in de tijd verschillen te ontwikkelen, wat het moeilijker maakt voor anderen om het te begrijpen en te onderhouden
1.9.2. Plaats opdrachten op afzonderlijke regels
Het is bij het lezen van code eenvoudig om opdrachten te missen als zij niet aan het begin van de regel staan. Bij het snel doorlezen van code worden vaak regels, die er niet uitzien als zoals u verwacht in de eerste tekens, over te slaan. Het is ook algemeen gebruik om een opdracht te verwachten na een voorwaarde, zoals if
.
Overweeg:
if (foo) bar();
baz(); bar();
Het is heel eenvoudig om delen van de beheersstroom te missen. Gebruik in plaats daarvan
if (foo)
bar();
baz();
bar();
1.9.3. Aanbevolen boeken
Effective Modern C++, Scott Meyers
More Effective C++, Scott Meyers
Effective STL, Scott Meyers
Design Patterns, GoF
U zou ook echt dit artikel moeten lezen uit Qt Quarterly ove designing Qt style (APIs)
1.10. Vermelding van bijdragen
Zij die nieuwe functies bijdragen worden aangemoedigd om mensen kennis te laten nemen van hun bijdrage door:
een opmerking toe te voegen in het log van wijzigingen voor de eerste versie waar de code is ingevoegd, in de vorm van:
This feature was funded by: Olmiomland https://olmiomland.ol This feature was developed by: Chuck Norris https://chucknorris.kr
een blogartikel te schrijven over de nieuwe mogelijkheid en dat toe te voegen aan de QGIS planet
hun naam toe te voegen aan: