Documentation Style for Examples: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Fix section structure so that coding style isn't a sub-section of file names; and fix example code, that seems to have been mangled, probably by some autoconversion.)
m (Fixed spelling mistake)
Line 9: Line 9:


:''The following is somewhat out of date in places.''
:''The following is somewhat out of date in places.''
== Example Documentation ==


* created with qdoc's <syntaxhighlight lang="c++" inline>\example</syntaxhighlight> command
==Example Documentation==
* title should end with "Example"
 
*created with qdoc's <syntaxhighlight lang="c++" inline="">\example</syntaxhighlight> command
*title should end with "Example"


The [[QDocExamples | Integrating Examples]] page explains how the command works with the QDoc variables to form URLs.
The [[QDocExamples | Integrating Examples]] page explains how the command works with the QDoc variables to form URLs.
Line 22: Line 23:
'''2.''' A 3-sentence description (minimum) consisting of ''how to find the example'' and ''what the example is''.
'''2.''' A 3-sentence description (minimum) consisting of ''how to find the example'' and ''what the example is''.
The description should answer the following:
The description should answer the following:
* if the example is runnable from Qt Creator, or from the install directory, or somewhere else.
 
* what the user should see when running the example.
*if the example is runnable from Qt Creator, or from the install directory, or somewhere else.
* should the user: see an application screen? or output from the command-line? a downloaded image or just a rectangle popping up?
*what the user should see when running the example.
* the primary topic the example addresses. ''Is it a Qt Network example or a Network and Connectivity example?''
*should the user: see an application screen? or output from the command-line? a downloaded image or just a rectangle popping up?
*the primary topic the example addresses. ''Is it a Qt Network example or a Network and Connectivity example?''


Examples:
Examples:
* "{Image Download} example is run by opening the "Image Download Example" from within Qt Creator."
 
* "The {NAME_OF_EXAMPLE} example pops up a screen which shows an image downloaded from the internet."
*"{Image Download} example is run by opening the "Image Download Example" from within Qt Creator."
* "{NAME_OF_EXAMPLE} shows how to download an image using QNetworkAccessManager and how to use the {Container Classes}{container classes}."
*"The {NAME_OF_EXAMPLE} example pops up a screen which shows an image downloaded from the internet."
*"{NAME_OF_EXAMPLE} shows how to download an image using QNetworkAccessManager and how to use the {Container Classes}{container classes}."
 
'''Note:''' It is acceptable to refer to the name of the example within the example, but use the command to mark the title.
'''Note:''' It is acceptable to refer to the name of the example within the example, but use the command to mark the title.


'''3.''' Link to relevant material.
'''3.''' Link to relevant material.
* Link to the main Qt topic. The topics are listed in http://doc.qt.io/qt-5/overviews-main.html
 
* Relate the example. Use <syntaxhighlight lang="c++" inline>\relates</syntaxhighlight> to relate to different example groups.
*Link to the main Qt topic. The topics are listed in http://doc.qt.io/qt-5/overviews-main.html
''' Make sure that the example is reachable from other articles as well.
*Relate the example. Use <syntaxhighlight lang="c++" inline="">\relates</syntaxhighlight> to relate to different example groups.
 
''' Make sure that the example is reachable from other articles as well.'''


'''Note:''' For simple examples, adding the following line ''Running the Example'' section. This is for convenience and should not be used if the text is not appropriate.
'''Note:''' For simple examples, adding the following line ''Running the Example'' section. This is for convenience and should not be used if the text is not appropriate.
<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
\include examples-run.qdocinc
\include examples-run.qdocinc
</syntaxhighlight>
</syntaxhighlight>
Line 45: Line 51:
This will include the text (taken from qtbase/doc/global):
This will include the text (taken from qtbase/doc/global):


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
\section1 Running the Example
\section1 Running the Example


Line 53: Line 59:
</syntaxhighlight>
</syntaxhighlight>


== "Tutorials", "Walkthroughs", or Detailed Example Documentation ==
=="Tutorials", "Walkthroughs", or Detailed Example Documentation==
''' ''Tutorials'', ''walkthroughs'' can be created with the <syntaxhighlight lang="c++" inline>\page</syntaxhighlight> command (if there is no source-code included).
''' ''Tutorials'', ''walkthroughs'' can be created with the <syntaxhighlight lang="c++" inline="">\page</syntaxhighlight> command (if there is no source-code included).'''
* These guidelines also apply to example documentation that have detailed documentation.
 
*These guidelines also apply to example documentation that have detailed documentation.


These are considered tutorials:
These are considered tutorials:
Line 65: Line 72:


'''2.''' Enhanced content. Choose at least one of a or b, or both:
'''2.''' Enhanced content. Choose at least one of a or b, or both:
* a. Show code snippets and a paragraph describing the snippet in addition to 1.
 
* b. a list of steps
*a. Show code snippets and a paragraph describing the snippet in addition to 1.
*b. a list of steps


'''3.''' For tutorials, or walkthroughs, use an explicit title or address a specific use. Choose either a or b, but not both:
'''3.''' For tutorials, or walkthroughs, use an explicit title or address a specific use. Choose either a or b, but not both:
* a. Add "Tutorial" at the end of the title
 
* b. Begin the title with a gerund (-ing words).
*a. Add "Tutorial" at the end of the title
*b. Begin the title with a gerund (-ing words).


Examples:
Examples:
* Image Download Tutorial
* Downloading an Image


*Image Download Tutorial
*Downloading an Image


== Writing Style ==
 
==Writing Style==
What is considered good writing style is inherently subjective. There is still some good advice that it normally pays to follow. Let's look at a few issues when Qt example documentation is concerned.
What is considered good writing style is inherently subjective. There is still some good advice that it normally pays to follow. Let's look at a few issues when Qt example documentation is concerned.


Try not to simply state what the code does line for line (the reader can easily figure that out by looking at the code and refer to the API documentation if he/she needs to). Focus on how things work behind the scenes and on issues that it is not easy to read from the code. On the other hand, we do not leave snippets uncommented; if you have nothing to say about a particular snippet, it is better to state what the code does line for line than leaving the space between two snippets empty. When implementing an advanced example, you can generally assume that the reader is familiar with basic Qt programming and concepts. So there is no need to explain everything in detail; again, focus on what the example tries to teach. For instance, an example that shows how to paint items in an item view does not need to explain what an item view is. There are no absolute rules to follow when deciding what needs explaining and what does not.
Try not to simply state what the code does line for line (the reader can easily figure that out by looking at the code and refer to the API documentation if he/she needs to). Focus on how things work behind the scenes and on issues that it is not easy to read from the code. On the other hand, we do not leave snippets uncommented; if you have nothing to say about a particular snippet, it is better to state what the code does line for line than leaving the space between two snippets empty. When implementing an advanced example, you can generally assume that the reader is familiar with basic Qt programming and concepts. So there is no need to explain everything in detail; again, focus on what the example tries to teach. For instance, an example that shows how to paint items in an item view does not need to explain what an item view is. There are no absolute rules to follow when deciding what needs explaining and what does not.


=== Example Code Guidelines ===
===Example Code Guidelines===
The example code should:
The example code should:
* follow the [[Coding Conventions]]
* should be compileable by the end-user
* be easier to understand
* runnable by the end-user


== The code itself ==
*follow the [[Coding Conventions]]
*should be compileable by the end-user
*be easier to understand
*runnable by the end-user
 
==The code itself==
In the code of an example, follow the [[Qt Coding Style]] and [[Coding Conventions]].
In the code of an example, follow the [[Qt Coding Style]] and [[Coding Conventions]].


=== File Names ===
===File Names===
The examples are as modularized as Qt itself. Each submodule can have a <syntaxhighlight lang="text" inline>examples</syntaxhighlight> directory containing examples. Examples within a submodule are organized in a directory hierarchy, ''e.g.'' <syntaxhighlight lang="text" inline>qtbase/examples/itemviews/dirview</syntaxhighlight> or <syntaxhighlight lang="text" inline>qtbase/examples/widgets/tetrix</syntaxhighlight>. The hierarchy is there only to group related examples together. The examples should have unique names even if the hierarchy didn't exist. All examples should be at the same depth in the hierarchy.
The examples are as modularized as Qt itself. Each submodule can have a <syntaxhighlight lang="text" inline="">examples</syntaxhighlight> directory containing examples. Examples within a submodule are organized in a directory hierarchy, ''e.g.'' <syntaxhighlight lang="text" inline="">qtbase/examples/itemviews/dirview</syntaxhighlight> or <syntaxhighlight lang="text" inline="">qtbase/examples/widgets/tetrix</syntaxhighlight>. The hierarchy is there only to group related examples together. The examples should have unique names even if the hierarchy didn't exist. All examples should be at the same depth in the hierarchy.


The example's <syntaxhighlight lang="text" inline>.pro</syntaxhighlight> file should have the same name as the directory it's in (''e.g.'' <syntaxhighlight lang="text" inline>tetrix.pro</syntaxhighlight> for <syntaxhighlight lang="text" inline>widgets/tetrix</syntaxhighlight>). The example name should only contain lowercase letters and digits, no hyphens, no underscores.
The example's <syntaxhighlight lang="text" inline="">.pro</syntaxhighlight> file should have the same name as the directory it's in (''e.g.'' <syntaxhighlight lang="text" inline="">tetrix.pro</syntaxhighlight> for <syntaxhighlight lang="text" inline="">widgets/tetrix</syntaxhighlight>). The example name should only contain lowercase letters and digits, no hyphens, no underscores.


In general, each class should be defined in its own header file and implemented in a corresponding .cpp file, ''e.g.'' MainWindow in mainwindow.h and mainwindow.cpp. Try to avoid defining more than one class per header file, since it confuses Java people and it's usually unnecessary, unless you have lots of small classes (''e.g.'' an undo/redo framework, with one class per type of action).
In general, each class should be defined in its own header file and implemented in a corresponding .cpp file, ''e.g.'' MainWindow in mainwindow.h and mainwindow.cpp. Try to avoid defining more than one class per header file, since it confuses Java people and it's usually unnecessary, unless you have lots of small classes (''e.g.'' an undo/redo framework, with one class per type of action).


Local classes may be defined in a .cpp file. Do not use the <syntaxhighlight inline>#include "foo.moc"</syntaxhighlight> trick in an example. (Don't worry if you don't understand what I'm talking about.)
Local classes may be defined in a .cpp file. Do not use the <syntaxhighlight inline="">#include "foo.moc"</syntaxhighlight> trick in an example. (Don't worry if you don't understand what I'm talking about.)


Always put your main() function in a separate file called main.cpp, and try to keep it as simple as possible. Most users have understood that main() is usually boring and seldom take the time to read it. It's therefore not the place to do unusual stuff.
Always put your main() function in a separate file called main.cpp, and try to keep it as simple as possible. Most users have understood that main() is usually boring and seldom take the time to read it. It's therefore not the place to do unusual stuff.


* '''Exception:''' If your example is very simple and requires only one file containing a main() function and (hopefully) a few other functions, call this file the same as your example (''e.g.'' tetrix.cpp), not main.cpp.
*'''Exception:''' If your example is very simple and requires only one file containing a main() function and (hopefully) a few other functions, call this file the same as your example (''e.g.'' tetrix.cpp), not main.cpp.


If you need images or other resources, use the resource mechanism. Call the resource file the same thing as the example, but with the .qrc extension (''e.g.'' tetrix.qrc). See the mainwindows/application example for an example of how to do this right.
If you need images or other resources, use the resource mechanism. Call the resource file the same thing as the example, but with the .qrc extension (''e.g.'' tetrix.qrc). See the mainwindows/application example for an example of how to do this right.


=== Include Files and Forward Declarations ===
===Include Files and Forward Declarations===
Use the Qt 4/Qt 5 syntax for #include files, and order them alphabetically:
Use the Qt 4/Qt 5 syntax for #include files, and order them alphabetically:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
#include <QApplication>
#include <QApplication>
#include <QComboBox>
#include <QComboBox>
Line 118: Line 129:
In your .h files, try to include as few headers as possible, using forward declarations when feasible in alphabetical order. Unless the example is meant to be a very simple one, appealing to a novice programmer, make your the example "Qt namespace aware" by wrapping the declarations of Qt classes in QT_BEGIN_NAMESPACE/QT_END_NAMESPACE:
In your .h files, try to include as few headers as possible, using forward declarations when feasible in alphabetical order. Unless the example is meant to be a very simple one, appealing to a novice programmer, make your the example "Qt namespace aware" by wrapping the declarations of Qt classes in QT_BEGIN_NAMESPACE/QT_END_NAMESPACE:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
#include <QDialog>
#include <QDialog>


Line 131: Line 142:
</syntaxhighlight>
</syntaxhighlight>


Best practice is to avoid "module includes", such as <syntaxhighlight inline>#include <QtGui></syntaxhighlight>, and use individual <syntaxhighlight inline>#include <QClass></syntaxhighlight> preprocessor directives instead. However, as the module includes reduces visual clutter you may use the <syntaxhighlight inline><QtGui></syntaxhighlight>, <syntaxhighlight inline><QtXml></syntaxhighlight>, etc., headers.
Best practice is to avoid "module includes", such as <syntaxhighlight inline="">#include <QtGui></syntaxhighlight>, and use individual <syntaxhighlight inline="">#include <QClass></syntaxhighlight> preprocessor directives instead. However, as the module includes reduces visual clutter you may use the <syntaxhighlight inline=""><QtGui></syntaxhighlight>, <syntaxhighlight inline=""><QtXml></syntaxhighlight>, etc., headers.


If you need standard C++ headers, use the new style of headers (''e.g.'' <syntaxhighlight inline><iostream></syntaxhighlight>) and put a <syntaxhighlight inline>using namespace std;</syntaxhighlight> after all the includes in .cpp files. Never use <syntaxhighlight inline>using</syntaxhighlight> directives in global namespace in header files.  
If you need standard C++ headers, use the new style of headers (''e.g.'' <syntaxhighlight inline=""><iostream></syntaxhighlight>) and put a <syntaxhighlight inline="">using namespace std;</syntaxhighlight> after all the includes in .cpp files. Never use <syntaxhighlight inline="">using</syntaxhighlight> directives in global namespace in header files.  


* '''Exception:''' For C headers, check whether you have used the .h name (<syntaxhighlight inline><math.h></syntaxhighlight>, not <syntaxhighlight inline><cmath></syntaxhighlight>) because the new name isn't supported by all compilers.
*'''Exception:''' For C headers, check whether you have used the .h name (<syntaxhighlight inline=""><math.h></syntaxhighlight>, not <syntaxhighlight inline=""><cmath></syntaxhighlight>) because the new name isn't supported by all compilers.


=== Include Order ===
===Include Order===
Arrange <syntaxhighlight inline>#includes</syntaxhighlight> in blocks, from most-specfic to most-common to make sure your headers are as self-contained as possible. Within a block of similar <syntaxhighlight inline>#includes</syntaxhighlight>, try to keep the order alphabetically.
Arrange <syntaxhighlight inline="">#includes</syntaxhighlight> in blocks, from most-specfic to most-common to make sure your headers are as self-contained as possible. Within a block of similar <syntaxhighlight inline="">#includes</syntaxhighlight>, try to keep the order alphabetically.


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
#include "mydialog.h"
#include "mydialog.h"
#include "yourdialog.h"
#include "yourdialog.h"
Line 153: Line 164:




=== Variable Names ===
===Variable Names===
In non-trivial projects there are often special rules on the naming of member variables, like prefixing them with "_" or "m_", or suffixing with "_". If your example can live without such markers, that's fine. If it can't, use the "m_" convention.
In non-trivial projects there are often special rules on the naming of member variables, like prefixing them with "_" or "m_", or suffixing with "_". If your example can live without such markers, that's fine. If it can't, use the "m_" convention.


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
void MyClass::setColor(const QColor &color)
void MyClass::setColor(const QColor &color)
{
{
Line 165: Line 176:
or
or


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
void MyClass::setColor(const QColor &c)
void MyClass::setColor(const QColor &c)
{
{
Line 174: Line 185:
Use the same variable name for parameters in header files as in the implementation. Don't drop the parameter names even if C++ lets you do so.
Use the same variable name for parameters in header files as in the implementation. Don't drop the parameter names even if C++ lets you do so.


=== C++ Preprocessor ===
===C++ Preprocessor===
Use the preprocessor exclusively to protect against multiple inclusion, ''e.g.''
Use the preprocessor exclusively to protect against multiple inclusion, ''e.g.''


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
#ifndef FOO_H
#ifndef FOO_H
#define FOO_H
#define FOO_H
Line 188: Line 199:
Don't use the QT_NO_xxx macros in examples. Instead, disable the example if it doesn't compile. We don't want the example source code, which is supposed to reflect end-user application code and be a model of clarity, to be littered with that junk.
Don't use the QT_NO_xxx macros in examples. Instead, disable the example if it doesn't compile. We don't want the example source code, which is supposed to reflect end-user application code and be a model of clarity, to be littered with that junk.


== Breaking Long Lines ==
==Breaking Long Lines==
Example code should wrap at 80 characters, because it's often quoted in the documentation and not all web browsers can display (or print) many more characters than that. This limit is stricter than the standard Trolltech limit of 100.
Example code should wrap at 80 characters, because it's often quoted in the documentation and not all web browsers can display (or print) many more characters than that. This limit is stricter than the standard Trolltech limit of 100.


Line 195: Line 206:
When breaking long lines, break right ''before'' an operator and try to align the lines in the standard Trolltech way:
When breaking long lines, break right ''before'' an operator and try to align the lines in the standard Trolltech way:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
int xxxxxx = alpha + (beta
int xxxxxx = alpha + (beta
                       * gamma);
                       * gamma);
Line 204: Line 215:
This rule applies to basically all operators:
This rule applies to basically all operators:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
outStream << "Foo"
outStream << "Foo"
           << "Bar";
           << "Bar";
</syntaxhighlight>
</syntaxhighlight>


One exception: With <syntaxhighlight inline>if</syntaxhighlight> and <syntaxhighlight inline>&&</syntaxhighlight> or <syntaxhighlight inline>||</syntaxhighlight>, you can rapidly end up having an unfortunate alignment problem:
One exception: With <syntaxhighlight inline="">if</syntaxhighlight> and <syntaxhighlight inline="">&&</syntaxhighlight> or <syntaxhighlight inline="">||</syntaxhighlight>, you can rapidly end up having an unfortunate alignment problem:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (dsfljfsfskjldsjkljklsjdk
if (dsfljfsfskjldsjkljklsjdk
     && fdsljsjdsdljklsjsjkdfs
     && fdsljsjdsdljklsjsjkdfs
Line 221: Line 232:
The problem is that it's not clear where the if condition ends (the third line) and where the if body starts (the fourth line). My ad hoc solution is to add four spaces to the continuation lines:
The problem is that it's not clear where the if condition ends (the third line) and where the if body starts (the fourth line). My ad hoc solution is to add four spaces to the continuation lines:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (dsfljfsfskjldsjkljklsjdk
if (dsfljfsfskjldsjkljklsjdk
         && fdsljsjdsdljklsjsjkdfs
         && fdsljsjdsdljklsjsjkdfs
Line 229: Line 240:
</syntaxhighlight>
</syntaxhighlight>


Fortunately, you don't need to do this for <syntaxhighlight inline>else if</syntaxhighlight> or <syntaxhighlight inline>while</syntaxhighlight>; unlike <syntaxhighlight inline>if</syntaxhighlight>, these aren't two-letter words.
Fortunately, you don't need to do this for <syntaxhighlight inline="">else if</syntaxhighlight> or <syntaxhighlight inline="">while</syntaxhighlight>; unlike <syntaxhighlight inline="">if</syntaxhighlight>, these aren't two-letter words.


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
while (dsfljfsfskjldsjkljklsjdk
while (dsfljfsfskjldsjkljklsjdk
       && fdsljsjdsdljklsjsjkdfs
       && fdsljsjdsdljklsjsjkdfs
Line 240: Line 251:




=== Spaces, Blank Lines, and Comments ===
===Spaces, Blank Lines, and Comments===
Apart when breaking lines, avoid aligning things together. This looks really bad with proportional fonts and actually looks bad with monospaced fonts as well. ''I.e.'' avoid
Apart when breaking lines, avoid aligning things together. This looks really bad with proportional fonts and actually looks bad with monospaced fonts as well. ''I.e.'' avoid


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
x = rect.x();
x = rect.x();
y = rect.y();
y = rect.y();
Line 252: Line 263:
Use blank lines consistently in your source files to separate functions in the .cpp file. Never use more than one blank line in a row, as this normally leads to inconsistent style.
Use blank lines consistently in your source files to separate functions in the .cpp file. Never use more than one blank line in a row, as this normally leads to inconsistent style.


Avoid comments. Documentation belongs exclusively in the example's walkthrough. (We don't have the resources to document the examples twice!) One case were comments are useful is when a parameter is unused:
Avoid comments. Documentation belongs exclusively in the example's walkthrough. (We don't have the resources to document the examples twice!) One case where comments are useful is when a parameter is unused:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
</syntaxhighlight>
</syntaxhighlight>
Line 260: Line 271:
This is better than
This is better than


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
void MandelbrotWidget::paintEvent(QPaintEvent *)
void MandelbrotWidget::paintEvent(QPaintEvent *)
</syntaxhighlight>
</syntaxhighlight>


== Braces ==
==Braces==
If syntax:
If syntax:
<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (x)
if (x)
     y;
     y;
Line 272: Line 283:


Never:
Never:
<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (x) y;
if (x) y;
</syntaxhighlight>
</syntaxhighlight>
Line 278: Line 289:
If y is complicated, you can use braces to make it clearer:
If y is complicated, you can use braces to make it clearer:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (x) {
if (x) {
     // do something strange
     // do something strange
Line 288: Line 299:
Same thing applies to for and while loops:
Same thing applies to for and while loops:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
for (int i = 0; i < n; ++i)
for (int i = 0; i < n; ++i)
     qDebug() << i;
     qDebug() << i;
Line 295: Line 306:
In the interest of readability, use braces whenever things start getting sightly complicated:
In the interest of readability, use braces whenever things start getting sightly complicated:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
for (int i = 0; i < n; ++i) {
for (int i = 0; i < n; ++i) {
     for (int j = 0; j < n; ++j) {
     for (int j = 0; j < n; ++j) {
Line 307: Line 318:
If you put braces around one case, do it around all:
If you put braces around one case, do it around all:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
if (x) {
if (x) {
     foo;
     foo;
Line 320: Line 331:
The advantage of this style is that you get nicely aligned braces at the bottom of the code, corresponding to the indentation level.
The advantage of this style is that you get nicely aligned braces at the bottom of the code, corresponding to the indentation level.


=== Signal-Slot Connections ===
===Signal-Slot Connections===
Always use the four- or five-parameter overload of the
Always use the four- or five-parameter overload of the
<syntaxhighlight lang="c++" inline>QObject::connect()</syntaxhighlight> call:
<syntaxhighlight lang="c++" inline="">QObject::connect()</syntaxhighlight> call:


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
connect(obj1, SIGNAL (foo()), this, SLOT (bar()));
connect(obj1, SIGNAL (foo()), this, SLOT (bar()));
</syntaxhighlight>
</syntaxhighlight>
Line 330: Line 341:
This is clearer than
This is clearer than


<syntaxhighlight lang="c++" line>
<syntaxhighlight lang="c++" line="">
connect(obj1, SIGNAL (foo()), SLOT (bar()));
connect(obj1, SIGNAL (foo()), SLOT (bar()));
</syntaxhighlight>
</syntaxhighlight>


Beginners might think that we're connecting to obj1's bar() slot, when we actually are connecting to <syntaxhighlight inline>this</syntaxhighlight>.
Beginners might think that we're connecting to obj1's bar() slot, when we actually are connecting to <syntaxhighlight inline="">this</syntaxhighlight>.


Always specify the full types of the arguments, ''i.e.'' <syntaxhighlight inline>const QString &</syntaxhighlight> instead of <syntaxhighlight inline>QString</syntaxhighlight>, in the interest of keeping things simple for beginners. We'll mention that you can write the latter in the documentation, but stick to a consistent, simple subset of the Qt language in examples.
Always specify the full types of the arguments, ''i.e.'' <syntaxhighlight inline="">const QString &</syntaxhighlight> instead of <syntaxhighlight inline="">QString</syntaxhighlight>, in the interest of keeping things simple for beginners. We'll mention that you can write the latter in the documentation, but stick to a consistent, simple subset of the Qt language in examples.

Revision as of 12:40, 18 April 2023

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

This page is part of the Qt Writing Guidelines.

This document is about how to write and document an example for Qt. When you have finished writing an example and its documentation, see the Integrating Examples page for information on making it work with Qt's build and documentation systems. See also Qt6/Example-Guideline for guidance on how to write the example itself, as opposed to its documentation.

The following is somewhat out of date in places.

Example Documentation

  • created with qdoc's \example command
  • title should end with "Example"

The Integrating Examples page explains how the command works with the QDoc variables to form URLs.

Requires the following:

1. A thumbnail image to represent its content. It could be the main screen or a specific area of the screen (for example, just the toolbar).

2. A 3-sentence description (minimum) consisting of how to find the example and what the example is. The description should answer the following:

  • if the example is runnable from Qt Creator, or from the install directory, or somewhere else.
  • what the user should see when running the example.
  • should the user: see an application screen? or output from the command-line? a downloaded image or just a rectangle popping up?
  • the primary topic the example addresses. Is it a Qt Network example or a Network and Connectivity example?

Examples:

  • "{Image Download} example is run by opening the "Image Download Example" from within Qt Creator."
  • "The {NAME_OF_EXAMPLE} example pops up a screen which shows an image downloaded from the internet."
  • "{NAME_OF_EXAMPLE} shows how to download an image using QNetworkAccessManager and how to use the {Container Classes}{container classes}."

Note: It is acceptable to refer to the name of the example within the example, but use the command to mark the title.

3. Link to relevant material.

Make sure that the example is reachable from other articles as well.

Note: For simple examples, adding the following line Running the Example section. This is for convenience and should not be used if the text is not appropriate.

\include examples-run.qdocinc

This will include the text (taken from qtbase/doc/global):

\section1 Running the Example

To run the example from {Qt Creator Manual}{Qt Creator}, open the Welcome
mode and select the example from Examples. For more information, visit
{Qt Creator: Building and Running an Example}{Building and Running an Example}.

"Tutorials", "Walkthroughs", or Detailed Example Documentation

Tutorials, walkthroughs can be created with the \page command (if there is no source-code included).

  • These guidelines also apply to example documentation that have detailed documentation.

These are considered tutorials: http://doc.qt.io/qtcreator-3.0/creator-running-targets.html https://doc.qt.io/qt-5/qtwidgets-widgets-digitalclock-example.html

Requires the following: 1. The same content as an example documentation. See Example Documentation section.

2. Enhanced content. Choose at least one of a or b, or both:

  • a. Show code snippets and a paragraph describing the snippet in addition to 1.
  • b. a list of steps

3. For tutorials, or walkthroughs, use an explicit title or address a specific use. Choose either a or b, but not both:

  • a. Add "Tutorial" at the end of the title
  • b. Begin the title with a gerund (-ing words).

Examples:

  • Image Download Tutorial
  • Downloading an Image


Writing Style

What is considered good writing style is inherently subjective. There is still some good advice that it normally pays to follow. Let's look at a few issues when Qt example documentation is concerned.

Try not to simply state what the code does line for line (the reader can easily figure that out by looking at the code and refer to the API documentation if he/she needs to). Focus on how things work behind the scenes and on issues that it is not easy to read from the code. On the other hand, we do not leave snippets uncommented; if you have nothing to say about a particular snippet, it is better to state what the code does line for line than leaving the space between two snippets empty. When implementing an advanced example, you can generally assume that the reader is familiar with basic Qt programming and concepts. So there is no need to explain everything in detail; again, focus on what the example tries to teach. For instance, an example that shows how to paint items in an item view does not need to explain what an item view is. There are no absolute rules to follow when deciding what needs explaining and what does not.

Example Code Guidelines

The example code should:

  • follow the Coding Conventions
  • should be compileable by the end-user
  • be easier to understand
  • runnable by the end-user

The code itself

In the code of an example, follow the Qt Coding Style and Coding Conventions.

File Names

The examples are as modularized as Qt itself. Each submodule can have a examples directory containing examples. Examples within a submodule are organized in a directory hierarchy, e.g. qtbase/examples/itemviews/dirview or qtbase/examples/widgets/tetrix. The hierarchy is there only to group related examples together. The examples should have unique names even if the hierarchy didn't exist. All examples should be at the same depth in the hierarchy.

The example's .pro file should have the same name as the directory it's in (e.g. tetrix.pro for widgets/tetrix). The example name should only contain lowercase letters and digits, no hyphens, no underscores.

In general, each class should be defined in its own header file and implemented in a corresponding .cpp file, e.g. MainWindow in mainwindow.h and mainwindow.cpp. Try to avoid defining more than one class per header file, since it confuses Java people and it's usually unnecessary, unless you have lots of small classes (e.g. an undo/redo framework, with one class per type of action).

Local classes may be defined in a .cpp file. Do not use the #include "foo.moc" trick in an example. (Don't worry if you don't understand what I'm talking about.)

Always put your main() function in a separate file called main.cpp, and try to keep it as simple as possible. Most users have understood that main() is usually boring and seldom take the time to read it. It's therefore not the place to do unusual stuff.

  • Exception: If your example is very simple and requires only one file containing a main() function and (hopefully) a few other functions, call this file the same as your example (e.g. tetrix.cpp), not main.cpp.

If you need images or other resources, use the resource mechanism. Call the resource file the same thing as the example, but with the .qrc extension (e.g. tetrix.qrc). See the mainwindows/application example for an example of how to do this right.

Include Files and Forward Declarations

Use the Qt 4/Qt 5 syntax for #include files, and order them alphabetically:

#include <QApplication>
#include <QComboBox>
#include <QStringList>

In your .h files, try to include as few headers as possible, using forward declarations when feasible in alphabetical order. Unless the example is meant to be a very simple one, appealing to a novice programmer, make your the example "Qt namespace aware" by wrapping the declarations of Qt classes in QT_BEGIN_NAMESPACE/QT_END_NAMESPACE:

#include <QDialog>

class MyClass;
class YourClass;

QT_BEGIN_NAMESPACE
class QCheckBox;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE

Best practice is to avoid "module includes", such as #include <QtGui>, and use individual #include <QClass> preprocessor directives instead. However, as the module includes reduces visual clutter you may use the <QtGui>, <QtXml>, etc., headers.

If you need standard C++ headers, use the new style of headers (e.g. <iostream>) and put a using namespace std; after all the includes in .cpp files. Never use using directives in global namespace in header files.

  • Exception: For C headers, check whether you have used the .h name (<math.h>, not <cmath>) because the new name isn't supported by all compilers.

Include Order

Arrange #includes in blocks, from most-specfic to most-common to make sure your headers are as self-contained as possible. Within a block of similar #includes, try to keep the order alphabetically.

#include "mydialog.h"
#include "yourdialog.h"

#include <QtGui>
#include <QtNetwork>

#include <iostream>

using namespace std;


Variable Names

In non-trivial projects there are often special rules on the naming of member variables, like prefixing them with "_" or "m_", or suffixing with "_". If your example can live without such markers, that's fine. If it can't, use the "m_" convention.

void MyClass::setColor(const QColor &color)
{
    m_color = color;
}

or

void MyClass::setColor(const QColor &c)
{
    color = c;
}

Use the same variable name for parameters in header files as in the implementation. Don't drop the parameter names even if C++ lets you do so.

C++ Preprocessor

Use the preprocessor exclusively to protect against multiple inclusion, e.g.

#ifndef FOO_H
#define FOO_H



#endif

Don't use the QT_NO_xxx macros in examples. Instead, disable the example if it doesn't compile. We don't want the example source code, which is supposed to reflect end-user application code and be a model of clarity, to be littered with that junk.

Breaking Long Lines

Example code should wrap at 80 characters, because it's often quoted in the documentation and not all web browsers can display (or print) many more characters than that. This limit is stricter than the standard Trolltech limit of 100.

The 80 character limit is liveable with. After all, Qt Quarterly is wrapped at 58 characters, and the entire Qt book is wrapped at 68 characters.

When breaking long lines, break right before an operator and try to align the lines in the standard Trolltech way:

int xxxxxx = alpha + (beta
                      * gamma);

Use a monospaced font when editing code. Never attempt to align code if you're using a proportional font.

This rule applies to basically all operators:

outStream << "Foo"
          << "Bar";

One exception: With if and && or ||, you can rapidly end up having an unfortunate alignment problem:

if (dsfljfsfskjldsjkljklsjdk
    && fdsljsjdsdljklsjsjkdfs
    && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}

The problem is that it's not clear where the if condition ends (the third line) and where the if body starts (the fourth line). My ad hoc solution is to add four spaces to the continuation lines:

if (dsfljfsfskjldsjkljklsjdk
        && fdsljsjdsdljklsjsjkdfs
        && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}

Fortunately, you don't need to do this for else if or while; unlike if, these aren't two-letter words.

while (dsfljfsfskjldsjkljklsjdk
       && fdsljsjdsdljklsjsjkdfs
       && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}


Spaces, Blank Lines, and Comments

Apart when breaking lines, avoid aligning things together. This looks really bad with proportional fonts and actually looks bad with monospaced fonts as well. I.e. avoid

x = rect.x();
y = rect.y();
width = rect.width();
height = rect.height();

Use blank lines consistently in your source files to separate functions in the .cpp file. Never use more than one blank line in a row, as this normally leads to inconsistent style.

Avoid comments. Documentation belongs exclusively in the example's walkthrough. (We don't have the resources to document the examples twice!) One case where comments are useful is when a parameter is unused:

void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)

This is better than

void MandelbrotWidget::paintEvent(QPaintEvent *)

Braces

If syntax:

if (x)
    y;

Never:

if (x) y;

If y is complicated, you can use braces to make it clearer:

if (x) {
    // do something strange
    yyyyyyyyy = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
    ''zzzzzzzzzzzzzzzzzzzzzz;
}

Same thing applies to for and while loops:

for (int i = 0; i < n; ++i)
    qDebug() << i;

In the interest of readability, use braces whenever things start getting sightly complicated:

for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
        for (int k = 0; k < n; ++k) {
            data[i][j][k] = i * j * k;
        }
    }
}

If you put braces around one case, do it around all:

if (x) {
    foo;
} else if (y) {
    bar;
    baz;
} else {
    blah;
}

The advantage of this style is that you get nicely aligned braces at the bottom of the code, corresponding to the indentation level.

Signal-Slot Connections

Always use the four- or five-parameter overload of the QObject::connect() call:

connect(obj1, SIGNAL (foo()), this, SLOT (bar()));

This is clearer than

connect(obj1, SIGNAL (foo()), SLOT (bar()));

Beginners might think that we're connecting to obj1's bar() slot, when we actually are connecting to this.

Always specify the full types of the arguments, i.e. const QString & instead of QString, in the interest of keeping things simple for beginners. We'll mention that you can write the latter in the documentation, but stick to a consistent, simple subset of the Qt language in examples.