当前位置: 首页 > 工具软件 > Qtc_AStyle > 使用案例 >

QT编码规范

法和安
2023-12-01

工作中需要用到QT项目,依据QT的一些官方文档做一些整理。

Qt 编码风格 Qt Coding Style

缩进 Indentation

  • 缩进为4个空格(4 spaces are used for indentation)
  • 使用空格作为缩进,不适用tab(Spaces, not tabs!)

变量声明 Declaring variables

  • 声明每一个变量都要用独立的一行(Declare each variable on a separate line)
  • 避免短的或无意义的命名(Avoid short or meaningless names (e.g. “a”, “rbarr”, “nughdeget”))
  • 单个字符的变量名只适用于非常明白该变量意思的场景下(比如临时变量)(Single character variable names are only okay for counters and temporaries, where the purpose of the variable is obvious)
  • 当一个变量被用到时再声明它(Wait when declaring a variable until it is needed)
 // Wrong
 int a, b;
 char *c, *d;
 
 // Correct
 int height;
 int width;
 char *nameOfThis;
 char *nameOfThat;
  • 变量和函数以小写字母开头。之后的部分每个单词以大写字母开头(Variables and functions start with a lower-case letter. Each consecutive word in a variable’s name starts with an upper-case letter)
  • 避免缩写(Avoid abbreviations)
 // Wrong
 short Cntr;
 char ITEM_DELIM = ' ';

 // Correct
 short counter;
 char itemDelimiter = ' ';
  • 类名以大写字母开头,公开类以Q开头,紧跟大写字母;公用函数以q开头。(此为Qt内部规范,我们可不遵守)(Classes always start with an upper-case letter. Public classes start with a ‘Q’ (QRgb) followed by an upper case letter. Public functions most often start with a ‘q’ (qRgb).)
  • 首字母缩写词采用驼峰命名法,如QXmlStreamReader,而不是QXMLStreamReader(即只有第一个字母大写)(Acronyms are camel-cased (e.g. QXmlStreamReader, not QXMLStreamReader).)

空白 Whitespace

  • 用空行在适当的地方划分代码块(Use blank lines to group statements together where suited)
  • 总是只用一个空行(Always use only one blank line)
  • 在关键词和花括号之间总是只用一个空格符(Always use a single space after a keyword and before a curly brace:)
 // Wrong
 if(foo){
 }

 // Correct
 if (foo) {
 }
  • 对于指针或引用,在类型名和*&之间用一个空格,但是在*&和变量名之间不要有空格(For pointers or references, always use a single space between the type and '*' or '&', but no space between the '*' or '&' and the variable name:
 char *x;
 const QString &myString;
 const char * const y = "hello";
  • 二元操作符的左右都要有空格(Surround binary operators with spaces)
  • 逗号后面需要一个空格(Leave a space after each comma)
  • cast类型装潢后无须空格(No space after a cast)
  • 避免C风格的cast类型转换(Avoid C-style casts when possible)
 // Wrong
 char* blockOfMemory = (char* ) malloc(data.size());

 // Correct
 char *blockOfMemory = reinterpret_cast<char *>(malloc(data.size()));
  • 不要在一行写多条语句(Do not put multiple statements on one line)
  • 另起一行写控制流语句的正文(By extension, use a new line for the body of a control flow statement:)
 // Wrong
 if (foo) bar();

 // Correct
 if (foo)
     bar();

括号 Braces

  • 使用紧贴括号:左括号和语句的开头在同一行,如果右括号是紧跟在一个关键词之后的,则右括号和该关键词在同一行(Use attached braces: The opening brace goes on the same line as the start of the statement. If the closing brace is followed by another keyword, it goes into the same line as well:)
 // Wrong
 if (codec)
 {
 }
 else
 {
 }

 // Correct
 if (codec) {
 } else {
 }
  • 例外:函数的实现和类的声明中,左括号总是在一行的开头(Exception: Function implementations (but not lambdas) and class declarations always have the left brace on the start of a line:)
 static void foo(int g)
 {
     qDebug("foo: %i", g);
 }

 class Moo
 {
 };
  • 当条件语句的执行部分多于一句的时候才使用花括号(Use curly braces only when the body of a conditional statement contains more than one line:)
 // Wrong
 if (address.isEmpty()) {
     return false;
 }

 for (int i = 0; i < 10; ++i) {
     qDebug("%i", i);
 }

 // Correct
 if (address.isEmpty())
     return false;

 for (int i = 0; i < 10; ++i)
     qDebug("%i", i);
  • 例外1:如果父语句占有多行,或经过多层封装,子语句要用到花括号(Exception 1: Use braces also if the parent statement covers several lines / wraps:)
 // Correct
 if (address.isEmpty() || !isValid()
     || !codec) {
     return false;
 }
  • 例外2:对称原则:在if-else语句块中,如果if或else中的一个包含了多行,另一个为了对称性原则,也要用花括号(Exception 2: Brace symmetry: Use braces also in if-then-else blocks where either the if-code or the else-code covers several lines:)
 // Wrong
 if (address.isEmpty())
     qDebug("empty!");
 else {
     qDebug("%s", qPrintable(address));
     it;
 }

 // Correct
 if (address.isEmpty()) {
     qDebug("empty!");
 } else {
     qDebug("%s", qPrintable(address));
     it;
 }

 // Wrong
 if (a)
     …
 else
     if (b)
         …

 // Correct
 if (a) {
     …
 } else {
     if (b)
         …
 }
  • 当条件语句的执行体是空语句的时候,用一个花括号(Use curly braces when the body of a conditional statement is empty)
 // Wrong
 while (a);

 // Correct
 while (a) {}

圆括号 Parentheses

  • 圆括号用来给语句分组(Use parentheses to group expressions:)
 // Wrong
 if (a && b || c)

 // Correct
 if ((a && b) || c)

 // Wrong
 a + b & c

 // Correct
 (a + b) & c

switch 语句 Switch statements

  • case标签和switch在同一列(The case labels are in the same column as the switch)
  • 每一个case语句的末尾都要有一个break语句或return语句,除非因功能需要故意不加或另外一个case是紧跟上一个case的。
 switch (myEnum) {
 case Value1:
   doSomething();
   break;
 case Value2:
 case Value3:
   doSomethingElse();
   Q_FALLTHROUGH();
 default:
   defaultHandling();
   break;
 }

跳转语句 (break, continue, return, and goto)

  • 不要在跳转关键词后边加else
 // Wrong
 if (thisOrThat)
     return;
 else
     somethingElse();

 // Correct
 if (thisOrThat)
     return;
 somethingElse();
  • 例外:如果这段代码是固有的对称结构,用else实现视觉上的对称也是可以的

换行 Line breaks

  • 每行代码不多于100个字符;若有必要,(Keep lines shorter than 100 characters; wrap if necessary)
    • 注释/apidoc行的实际文字应该保持80列以内。适应周围环境,并尝试以避免“锯齿状”段落的方式排列文本。(Comment/apidoc lines should be kept below 80 columns of actual text. Adjust to the surroundings, and try to flow the text in a way that avoids “jagged” paragraphs.)
  • 逗号位于换行的末尾;操作员从新线路的开头开始。如果编辑器太窄,则很容易错过行尾的运算符。(Commas go at the end of wrapped lines; operators start at the beginning of the new lines. An operator at the end of the line is easy to miss if the editor is too narrow.)
 // Wrong
 if (longExpression +
     otherLongExpression +
     otherOtherLongExpression) {
 }

 // Correct
 if (longExpression
     + otherLongExpression
     + otherOtherLongExpression) {
 }

一般例外 General exceptions

  • 当严格遵守规则使您的代码看起来很糟糕时,请随时破坏它。(When strictly following a rule makes your code look bad, feel free to break it.)
  • 如果任何给定模块存在争议,维护者对接受的风格拥有最终决定权(根据The Qt Governance Model)。(If there is a dispute in any given module, the Maintainer has the final say on the accepted style (as per The Qt Governance Model).)

Artistic Style

以下选项可以用来格式化你的代码

--style=kr 
--indent=spaces=4 
--align-pointer=name 
--align-reference=name 
--convert-tabs 
--attach-namespaces
--max-code-length=100 
--max-instatement-indent=120 
--pad-header
--pad-oper

Note that “unlimited” --max-instatement-indent is used only because astyle is not smart enough to wrap the first argument if subsequent lines would need indentation limitation. You are encouraged to manually limit in-statement-indent to roughly 50 colums:

    int foo = some_really_long_function_name(and_another_one_to_drive_the_point_home(
            first_argument, second_argument, third_arugment));

clang-format

你可以使用clang-formatgit-clang-format来重新格式化你的代码。qt5的git仓库提供了一个 _clang-format的文件来设置Qt代码的格式规范。你可以把它拷贝到你的根目录并让clang-format使用它。

# Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
#
# You may use this file under the terms of the 3-clause BSD license.
# See the file LICENSE from this package for details.

# This is the clang-format configuration style to be used by Qt,
# based on the rules from https://wiki.qt.io/Qt_Coding_Style and
# https://wiki.qt.io/Coding_Conventions

---
# Webkit style was loosely based on the Qt style
BasedOnStyle: WebKit

Standard: c++17

# Column width is limited to 100 in accordance with Qt Coding Style.
# https://wiki.qt.io/Qt_Coding_Style
# Note that this may be changed at some point in the future.
ColumnLimit: 100
# How much weight do extra characters after the line length limit have.
# PenaltyExcessCharacter: 4

# Disable reflow of some specific comments
# qdoc comments: indentation rules are different.
# Translation comments and SPDX license identifiers are also excluded.
CommentPragmas: "^!|^:|^ SPDX-License-Identifier:"

# We want a space between the type and the star for pointer types.
PointerBindsToType: false

# We use template< without space.
SpaceAfterTemplateKeyword: false

# We want to break before the operators, but not before a '='.
BreakBeforeBinaryOperators: NonAssignment

# Braces are usually attached, but not after functions or class declarations.
BreakBeforeBraces: Custom
BraceWrapping:
    AfterClass: true
    AfterControlStatement: false
    AfterEnum: false
    AfterFunction: true
    AfterNamespace: false
    AfterObjCDeclaration: false
    AfterStruct: true
    AfterUnion: false
    BeforeCatch: false
    BeforeElse: false
    IndentBraces: false

# When constructor initializers do not fit on one line, put them each on a new line.
ConstructorInitializerAllOnOneLineOrOnePerLine: true
# Indent initializers by 4 spaces
ConstructorInitializerIndentWidth: 4

# Indent width for line continuations.
ContinuationIndentWidth: 8

# No indentation for namespaces.
NamespaceIndentation: None

# Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125
IndentPPDirectives: AfterHash
# We only indent with 2 spaces for preprocessor directives
PPIndentWidth: 2

# Horizontally align arguments after an open bracket.
# The coding style does not specify the following, but this is what gives
# results closest to the existing code.
AlignAfterOpenBracket: true
AlwaysBreakTemplateDeclarations: true

# Ideally we should also allow less short function in a single line, but
# clang-format does not handle that.
AllowShortFunctionsOnASingleLine: Inline

# The coding style specifies some include order categories, but also tells to
# separate categories with an empty line. It does not specify the order within
# the categories. Since the SortInclude feature of clang-format does not
# re-order includes separated by empty lines, the feature is not used.
SortIncludes: false

# macros for which the opening brace stays attached.
ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]

# Break constructor initializers before the colon and after the commas.
BreakConstructorInitializers: BeforeColon

# Add "// namespace <namespace>" comments on closing brace for a namespace
# Ignored for namespaces that qualify as a short namespace,
# see 'ShortNamespaceLines'
FixNamespaceComments: true

# Definition of how short a short namespace is, default 1
ShortNamespaceLines: 1

# When escaping newlines in a macro attach the '\' as far left as possible, e.g.
##define a     \
#   something; \
#   other;     \
#   thelastlineislong;
AlignEscapedNewlines: Left

# Avoids the addition of a space between an identifier and the
# initializer list in list-initialization.
SpaceBeforeCpp11BracedList: false

编码约定 Coding Conventions

API Design Principles

参考

Qt Coding Style
Coding Conventions
UI Text Conventions
API Design Principles
Google C++ Style Guide
Designing Qt-Style C++ APIs

 类似资料: