Documentation Style for Examples: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(Redirect readers to new Qt 6 page)
Tags: Replaced Visual edit
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Writing Guidelines]]
This page is obsolete and deprecated. For Qt 6 equivalent, see [[Writing Example Documentation and Tutorials]]
[[Category:Developing Qt::Examples]]
{{LangSwitch}}
This page is part of the [[Qt Writing Guidelines]].
See also:
# [[QDocExamples|Integrating Examples]]  - QDoc configuration
# [[Qt6/Example-Guideline]] - Writing example code
 
==Example Documentation and Tutorials==
 
Qt 6 examples have an accompanying '''documentation'''. This documentation should describe the example's themes and which Qt modules or tools are used. An accompanying image is important to show UI related elements and the expected output should be clear.
 
A '''tutorial''' goes beyond a description, outlining particular steps and highlighting the important parts of the example. The tutorial should ''walk through'' the code and gloss over topics related to Qt. Notes and other information should supplement the walk-through, giving insight and reason for the particular code.
 
Essentially, the '''minimum example documentation''' should contain:
 
# Example page - QDoc's '''\example''' command creates the example page. The \example command specifies the directory.
# Title - QDoc's '''\title''' command. The title should be simple and descriptive
# Brief description - '''\brief''' command and a small description of the example's theme
# Example category - label the example documentation with '''\examplecategory''' to assign it to a membership. For example ''Connectivity'', ''Desktop'', and so on.
# Main body - one or several paragraphs that describe the example's themes and expected behavior
# Running instruction - describe where to find the example (see '''Sample Text: Running Instruction''' section)
# References - add links to related documentation, overview, or other supplementary material
# Licenses - add the '''Commercial/BSD 3 clause license'''.
# Image - especially useful for GUI related examples. Qt Creator can show these images as thumbnails.
 
 
The '''minimum tutorial''' fulfills the minimum example documentation, and the following:
 
#Code snippets - show and analyze the code in a granular (line-by-line) or holistic (the principle and goal) way.
#Step-by-step instruction - show the progression from start to finish. A similar style is meal recipes, but do not follow strictly.
#Insight - provide insight to the code structure and Qt usage. A possible reason may be code security, scalability, usability, and so on.
#Verb-focused title - Emphasize the action or verb in the title. Use the '''gerund''', typically ending in ''-ing.'' For example, ''drawing'', ''integrating'', ''handling'', ''processing'', ''and so on.''
 
 
'''The sections below provide sample text for the requirements for example documentation and tutorial'''
 
=== Sample Text: Brief Description ===
 
=== Sample Text: Running Instruction ===
Example documentation and tutorials should outline the requirements and steps for building and running the example. Ideally, Qt Creator can open and launch the example, but some examples may need additional tools or environment.
 
We aim for consistency and the following text is appropriate to inform about running examples from within Qt Creator. Feel free to modify and adapt to the specific example.
 
At the bottom of your example documentation (same area as the '''\page''' command), add:<syntaxhighlight lang="c++" line="">
\include examples-run.qdocinc
</syntaxhighlight>
 
This will include the text (taken from qtbase/doc/global):
 
<syntaxhighlight lang="c++" line="">
\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}.
</syntaxhighlight>
 
=== Sample Text: Licenses ===
 
For example code, use the '''Commercial/BSD 3 clause license''':
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
The example documentation and tutorial can be under a specific '''Commercial/GFDL 1.3''' documentation license:
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
 
 
Sample Text: Tutorial Titles
 
===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 <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.
 
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.)
 
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:
 
<syntaxhighlight lang="c++" line="">
#include <QApplication>
#include <QComboBox>
#include <QStringList>
</syntaxhighlight>
 
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="">
#include <QDialog>
 
class MyClass;
class YourClass;
 
QT_BEGIN_NAMESPACE
class QCheckBox;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE
</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.
 
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.
 
===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.
 
<syntaxhighlight lang="c++" line="">
#include "mydialog.h"
#include "yourdialog.h"
 
#include <QtGui>
#include <QtNetwork>
 
#include <iostream>
 
using namespace std;
</syntaxhighlight>
 
 
===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.
 
<syntaxhighlight lang="c++" line="">
void MyClass::setColor(const QColor &color)
{
    m_color = color;
}
</syntaxhighlight>
 
or
 
<syntaxhighlight lang="c++" line="">
void MyClass::setColor(const QColor &c)
{
    color = c;
}
</syntaxhighlight>
 
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.''
 
<syntaxhighlight lang="c++" line="">
#ifndef FOO_H
#define FOO_H
 
 
#endif
</syntaxhighlight>
 
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:
 
<syntaxhighlight lang="c++" line="">
int xxxxxx = alpha + (beta
                      * gamma);
</syntaxhighlight>
 
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:
 
<syntaxhighlight lang="c++" line="">
outStream << "Foo"
          << "Bar";
</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:
 
<syntaxhighlight lang="c++" line="">
if (dsfljfsfskjldsjkljklsjdk
    && fdsljsjdsdljklsjsjkdfs
    && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}
</syntaxhighlight>
 
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="">
if (dsfljfsfskjldsjkljklsjdk
        && fdsljsjdsdljklsjsjkdfs
        && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}
</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.
 
<syntaxhighlight lang="c++" line="">
while (dsfljfsfskjldsjkljklsjdk
      && fdsljsjdsdljklsjsjkdfs
      && dsfljkdfjkldksdfjdjkfdksfdkjld) {
    sadjdjddadhsad;
}
</syntaxhighlight>
 
 
===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
 
<syntaxhighlight lang="c++" line="">
x = rect.x();
y = rect.y();
width = rect.width();
height = rect.height();
</syntaxhighlight>
 
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:
 
<syntaxhighlight lang="c++" line="">
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
</syntaxhighlight>
 
This is better than
 
<syntaxhighlight lang="c++" line="">
void MandelbrotWidget::paintEvent(QPaintEvent *)
</syntaxhighlight>
 
==Braces==
If syntax:
<syntaxhighlight lang="c++" line="">
if (x)
    y;
</syntaxhighlight>
 
Never:
<syntaxhighlight lang="c++" line="">
if (x) y;
</syntaxhighlight>
 
If y is complicated, you can use braces to make it clearer:
 
<syntaxhighlight lang="c++" line="">
if (x) {
    // do something strange
    yyyyyyyyy = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
    ''zzzzzzzzzzzzzzzzzzzzzz;
}
</syntaxhighlight>
 
Same thing applies to for and while loops:
 
<syntaxhighlight lang="c++" line="">
for (int i = 0; i < n; ++i)
    qDebug() << i;
</syntaxhighlight>
 
In the interest of readability, use braces whenever things start getting sightly complicated:
 
<syntaxhighlight lang="c++" line="">
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;
        }
    }
}
</syntaxhighlight>
 
If you put braces around one case, do it around all:
 
<syntaxhighlight lang="c++" line="">
if (x) {
    foo;
} else if (y) {
    bar;
    baz;
} else {
    blah;
}
</syntaxhighlight>
 
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
<syntaxhighlight lang="c++" inline="">QObject::connect()</syntaxhighlight> call:
 
<syntaxhighlight lang="c++" line="">
connect(obj1, SIGNAL (foo()), this, SLOT (bar()));
</syntaxhighlight>
 
This is clearer than
 
<syntaxhighlight lang="c++" line="">
connect(obj1, SIGNAL (foo()), SLOT (bar()));
</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.

Latest revision as of 15:25, 20 November 2024

This page is obsolete and deprecated. For Qt 6 equivalent, see Writing Example Documentation and Tutorials