중요
번역은 여러분이 참여할 수 있는 커뮤니티 활동입니다. 이 페이지는 현재 96.08% 번역되었습니다.
1. QGIS 코드 작업 표준
QGIS coding standards are described in the policy document available at QEP #314. All developers are required to follow those policies. Please note that QEP #314 is a live document, and that these policies may change over time.
1.1. 클래스
1.1.1. 접근자 함수
접근자가 const
로 정확히 표시되도록 신경을 쓰십시오. 그렇게 하는 것이 적절한 경우, 캐시된 값 유형인 멤버 변수를 mutable
로 표시해야 할 수도 있습니다.
1.1.2. 함수 인자
참조를 통해 인자를 전달해야 하는 경우 특히 신경을 써야 합니다. 인자 객체가 (QPoint 객체처럼) 소용량이고 평범하게 복사되는 경우가 아니라면, 상수 참조로 전달해야 합니다. Qt API와 일관성을 지키기 위해, 내재적으로 공유된 객체일지라도 상수 참조로 전달됩니다. (예를 들어 setTitle( QString title )
이 아니라 setTitle( const QString& title )
을 써야 합니다.)
1.1.3. 함수 반환 값
소용량이고 평범하게 복사된 객체를 값으로 반환합니다. 대용량 객체는 상수 참조로 반환되어야 합니다. 이 규칙의 단 한 가지 예외는 내재적으로 공유된 객체로, 언제나 값으로 반환됩니다. QObject
또는 하위 클래스 객체는 포인터로 반환합니다.
int maximumValue() const
const LayerSet& layers() const
QString title() const
(QString
은 내재적으로 공유되었습니다)QList< QgsMapLayer* > layers() const
(QList
는 내재적으로 공유되었습니다)QgsVectorLayer *layer() const;
(QgsVectorLayer
는QObject
를 상속합니다)QgsAbstractGeometry *geometry() const;
(QgsAbstractGeometry
는 추상이기 때문에 캐스트해야 할 수도 있습니다)
1.2. API 문서
공개 API에서 사용할 수 있는 모든 클래스, 메소드, 목록(enum), 기타 코드에 대해 API 문서를 작성해야만 합니다.
QGIS는 문서화 작업에 Doxygen 을 사용합니다. 독자가 어떤 것을 기대할 수 있는지, 첨단 사례의 경우 어떤 일이 일어나는지에 대한 정보를 제공하는, 그리고 독자가 찾아볼 수 있는 다른 인터페이스들에 대한 힌트를 알려주는 서술적이고 의미 있는 주석과 함께 최적의 예제와 코드 예시를 작성하십시오.
1.2.1. 멤버 변수
멤버 변수는 일반적으로 private
부분에 있어야 하며 게터(getter)와 세터(setter)를 통해 사용할 수 있어야 합니다. 이 규칙의 단 한 가지 예외는 오류 보고 작업 용 같은 데이터 컨테이너들입니다. 이런 경우 멤버의 이름 앞에 m
접두어를 붙이지 마십시오.
1.3. Qt 설계자
1.3.1. 생성된 클래스들
Qt 설계자(Qt Designer)의 (UI) 파일들로부터 생성된 QGIS 클래스들은 Base
접미어를 가져야 합니다. 이 접미어가 해당 클래스를 Qt 설계자가 생성한 기반 클래스로 식별하게 합니다.
예시:
QgsPluginManagerBase
QgsUserOptionsBase
1.3.2. 대화창
모든 대화창은 모든 툴바 아이콘과 기타 관련 위젯들을 위한 툴팁 도움말을 구현해야 합니다. 툴팁은 신규 사용자와 경험이 풍부한 사용자 모두의 기능 검색 가능성을 크게 높여줍니다.
대화창의 레이아웃이 변경될 때마다 위젯의 탭 순서가 업데이트되는지 확인하십시오.
1.4. C++ 파일
1.4.1. 표준 헤더와 사용 허가
각 소스 파일은 다음 예시처럼 패턴화된 헤더 부분을 담고 있어야 합니다:
/***************************************************************************
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.
*
***************************************************************************/
참고
깃 저장소에 Qt 설계자 용 템플릿이 있습니다. 이 템플릿을 사용하려면, qt_creator_license_template 에서 로컬 위치로 복사한 다음 메일 주소와 — 필요한 경우 — 이름을 조정하고 QtCreator가 이를 사용할 수 있도록 환경설정하십시오:
1.5. 편집 작업
다음 요구 사항을 만족시킨다면 어떤 텍스트 편집기/IDE라도 QGIS 코드를 편집하는 데 사용할 수 있습니다.
1.5.1. 탭
여러분의 편집기가 공백들을 가진 탭을 에뮬레이트(emulate)하도록 설정하십시오. 탭 간격을 2칸으로 (스페이스 바를 2번 누른 간격으로) 설정해야 합니다.
참고
빔(Vim) 편집기에서는 set expandtab ts=2
명령어로 설정할 수 있습니다.
1.5.2. 들여쓰기
가독성을 향상시키기 위해 소스 코드를 들여쓰기해야 합니다. 변경된 파일을 검색한 다음 Astyle(Artistic Style) 을 사용해서 다시 들여쓰기해주는 prepare_commit.sh 파일이 있습니다. 소스 코드를 커밋하기 전에 이 파일을 실행해야 합니다. 개별 파일들을 들여쓰기하려면 astyle.sh 파일을 사용해도 됩니다.
Astyle의 신 버전이 소스를 완전히 다시 들여쓰기하는 데 쓰이는 버전과는 다르게 들여쓰기를 하기 때문에, 이 스크립트는 저장소에 포함된 옛 Astyle 버전을 사용합니다. (빌드 시 이 옛 버전을 포함시키려면 CMake에서 WITH_ASTYLE
을 활성화시키십시오.)
1.6. API 호환성
C++ 용 API 문서 가 있습니다.
우리는 API를 안정적으로 유지하고 이전 버전과 호환되도록 하려 합니다. API 정리(cleanup)는 다음과 같이 Qt 소스 코드와 비슷한 방식으로 이루어져야 합니다.
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 바인딩
SIP 파일들의 일부는 전용 스크립트를 사용해서 자동 생성됩니다.
1.7.1. 헤더 전처리
C++ 헤더 파일에서 SIP 파일을 적절하게 빌드하기 위한 모든 정보를 찾아야만 합니다. 이런 정의에 사용할 수 있는 매크로가 몇 개 있습니다:
SIP 파일에만 코드를 생성하려면
#ifdef SIP_RUN
을 사용하고, 또는 C++ 코드만 생성하려면#ifndef SIP_RUN
을 사용하십시오. 두 경우 모두#else
선언문을 처리합니다.어떤 줄을 삭제하려면
SIP_SKIP
을 사용하십시오.다음과 같은 주석(annotation)들을 처리합니다:
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/
이 블록에
#ifdef SIP_RUN
선언문을 사용하지 않는 한private
부분은 보이지 않습니다.SIP_PYDEFAULTVALUE(value)
를 사용해서 파이썬 메소드의 기본값을 대체할 값을 정의할 수 있습니다. 기본값이 쉼표,
를 담고 있는 경우, 값을 작은따옴표'
로 둘러싸야 합니다.SIP_PYTYPE(type)
을 사용해서 파이썬 메소드의 인자에 대한 대체 유형을 정의할 수 있습니다. 유형이 쉼표,
를 담고 있는 경우, 유형을 작은따옴표'
로 둘러싸야 합니다.
sipifyheader.h 데모 파일도 사용할 수 있습니다.
1.7.2. SIP 파일 생성하기
SIP 파일은 다음처럼 전용 스크립트를 사용해서 생성할 수 있습니다:
scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip
새로 추가된 C++ 파일의 SIP 파일을 자동 생성하려면 sip_include.sh 를 실행해야 합니다.
As soon as a SIP file is added to one of the source file (core_auto.sip, gui_auto.sip or analysis_auto.sip), it will be considered as generated automatically. A test will ensure that this file is up to date with its corresponding header.
SIP 파일을 강제로 다시 생성하려면, sipify_all.sh 를 실행해야 합니다.
1.7.3. sipify 스크립트 향상시키기
If some improvements are required for sipify script, please add the missing bits
to the demo file sipifyheader.h
and create the expected header sipifyheader.expected.sip
file.
This will also be automatically tested as a unit test of the script itself.
1.8. 설정
QGIS 코드 베이스는 설정을 선언하고, 등록하고, 사용할 수 있는 메커니즘을 제공합니다.
설정은 사용할 수 있는 구현들 (QgsSettingsEntryString, QgsSettingsEntryInteger, …) 가운데 하나를 사용해서 정의해야 합니다.
설정은 반드시 설정 트리(QgsSettingsTree)에 통합되어야만 합니다. 상위 노드(QgsSettingsTreeNode)를 가진 작성자(constructor)를 사용하면 자동으로 통합시킵니다.
설정은 전용 클래스에 또는 레지스트리(core, gui, app, …)에 직접
const static
으로 선언됩니다.설정 키는
kebab-case
케밥 표기법을 따르는 형식이어야 합니다.
1.9. 코드 작업 스타일
이 절에서는 오류, 개발 시간, 그리고 유지·관리에 드는 수고를 줄여주리라 기대되는 몇몇 프로그래밍 힌트와 도움말을 설명합니다.
1.9.1. 가능한 부분마다 코드를 일반화하기
여러분이 코드를 잘라내서 붙여넣거나 또는 그러지 않고 동일한 내용을 한 번 이상 작성하는 경우, 해당 코드를 단일 함수로 통합하는 것을 고려해보십시오.
이렇게 하면:
여러 위치에서가 아니라 한 위치에서 변경 사항을 만들 수 있게 됩니다.
코드가 지저분해지는 일을 막는 데 도움이 됩니다.
시간이 지남에 따라 여러 복사본들이 서로 다르게 발전해서 다른 사람들이 코드를 이해하고 유지·보수하기 어려워지는 일을 방지할 수 있게 해줍니다.
1.9.2. 명령어는 서로 다른 줄에 넣기
코드를 읽을 때 명령어가 그 줄의 맨 앞에 없다면 놓치기 쉽습니다. 코드를 빨리 훑어볼 때, 처음 몇 문자들이 여러분이 찾는 내용처럼 보이지 않을 경우 그 줄을 건너뛰어버리는 일도 흔합니다. 또한 if
같은 조건문 뒤에 명령어가 오는 것을 기대하는 일도 흔합니다.
다음을 보십시오:
if (foo) bar();
baz(); bar();
정말 쉽게 제어 흐름의 일부분을 놓칠 수 있습니다. 대신 다음을 사용하십시오:
if (foo)
bar();
baz();
bar();
1.9.3. 권장 도서
Effective Modern C++, 스콧 마이어스(Scott Meyers)
More Effective C++, 스콧 마이어스(Scott Meyers)
Effective STL, 스콧 마이어스(Scott Meyers)
Design Patterns, GoF(Gang of Four)
계간 Qt(Qt Quarterly)에 나온 Qt 스타일 설계하기 (APIs) 라는 기사도 읽어봐야 할 것입니다.
1.10. 공헌에 대한 인정
새 함수를 만든 공헌자들이 사람들에게 자신의 공헌을 다음과 같은 방법으로 알릴 것을 권장합니다:
코드를 통합시킨 첫 번째 버전에 대한 변경 로그에 다음 형식으로 된 짧은 문장을 추가하기:
This feature was funded by: Olmiomland https://olmiomland.ol This feature was developed by: Chuck Norris https://chucknorris.kr
writing an article about the new feature on a blog, and add it to QGIS Planet
공헌자들의 이름을 다음에 추가하기: