Writing Qt Examples: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Removed irrelevant content. There is a writing style guide for examples already.)
No edit summary
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
This page is part of the [[QtWritingGuidelines | Qt Writing Guidelines]].
This page is part of the [[QtWritingGuidelines | Qt Writing Guidelines]].


This document is about how to write an example for Qt. When you have finished writing an example and its documentation, see the [[Integrating Qt Examples]] page for information on making it work with Qt's build and documentation systems.
Qt examples follows the Qt Project's [https://contribute.qt-project.org/quips QUIP] policy system.


In particular, '''QUIP-13''' specifies the construction of the example, how to name the files, and other conventions that examples should follow.
*[https://contribute.qt-project.org/quips/13 QUIP-13] '''Qt Examples'''
Additionally, here are wiki pages that clarify or extend the official QUIP, by giving tips and hints for examples and its documentation.
*[[Writing Example Documentation and Tutorials]] - writing example documentation and tutorials
*[[Contributing Examples to Qt]]  - configuring QDoc and submitting examples to Qt repositories
*[[Qt Examples in Qt Creator]] - how to ensure the example shows up in Qt Creator
== File Names ==
== File Names ==


Line 22: Line 28:
== Include Files and Forward Declarations ==
== Include Files and Forward Declarations ==


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


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


* '''Exception:''' For C headers, check whether you have use the .h name (<code inline><math.h></code>, not <code inline><cmath></code>) because the new name isn't supported by all compilers.
* '''Exception:''' For C headers, check whether you have use the .h name (<code inline><math.h></code>, not <code inline><cmath></code>) because the new name isn't supported by all compilers
 
== Include order ==
 
Arrange <code inline>#includes</code>in blocks, from most-specfic to most-common to make sure your headers are as self-contained as possible. Within a block of similar <code inline>#includes</code>, try to keep the order alphabetically.
 
<code>
#include "mydialog.h"
#include "yourdialog.h"
 
#include <QtGui>
#include <QtNetwork>
 
#include <iostream>
 
using namespace std;
</code>
 
== 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.
 
<code>
void MyClass::setColor(const QColor &color)
{
m_color = color;
}
</code>
 
or
 
<code>
void MyClass::setColor(const QColor &c)
{
color = c;
}
</code>
 
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.''
 
<code>
#ifndef FOO_H
#define FOO_H
 
 
#endif
</code>
 
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:
 
<code>
int xxxxxx = alpha + (beta
* gamma);
</code>
 
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:
 
<code>
outStream << "Foo"
<< "Bar";
</code>
 
One exception: With <code inline>if</code> and <code inline>&&</code> or <code inline>||</code>, you can rapidly end up having an unfortunate alignment problem:
 
<code>
if (dsfljfsfskjldsjkljklsjdk
&& fdsljsjdsdljklsjsjkdfs
&& dsfljkdfjkldksdfjdjkfdksfdkjld)
sadjdjddadhsad;
</code>
 
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:
 
<code>
if (dsfljfsfskjldsjkljklsjdk
&& fdsljsjdsdljklsjsjkdfs
&& dsfljkdfjkldksdfjdjkfdksfdkjld)
sadjdjddadhsad;
</code>
 
Fortunately, you don't need to do this for <code inline>else if</code> or <code inline>while</code>; unlike <code inline>if</code>, these aren't two-letter words.
 
<code>
while (dsfljfsfskjldsjkljklsjdk
&& fdsljsjdsdljklsjsjkdfs
&& dsfljkdfjkldksdfjdjkfdksfdkjld)
sadjdjddadhsad;
</code>
 
== 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
 
<code>
x = rect.x();
y = rect.y();
width  = rect.width();
height = rect.height();
</code>
 
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:
 
<code>
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
</code>
 
This is better than
 
<code>
void MandelbrotWidget::paintEvent(QPaintEvent *)
</code>
 
== Braces ==
 
If syntax:
 
<code>
if (x)
y;
</code>
 
Never:
 
<code>
if (x) y;
</code>
 
If y is complicated, you can use braces to make it clearer:
 
<code>
if (x) {
// do something strange
yyyyyyyyy = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
''zzzzzzzzzzzzzzzzzzzzzz;
}
</code>
 
Same thing applies to for and while loops:
 
<code>
for (int i = 0; i < n;i)
qDebug() << i;
</code>
 
In the interest of readability, use braces whenever things start getting sightly complicated:
 
<code>
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;
}
}
}
</code>
 
If you put braces around one case, do it around all:
 
<code>
if (x) {
foo;
} else if (y) {
bar;
baz;
} else {
blah;
}
</code>
 
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
<code inline>QObject::connect()</code> call:
 
<code>
connect(obj1, SIGNAL (foo()), this, SLOT (bar()));
</code>
 
This is clearer than
 
<code>
connect(obj1, SIGNAL (foo()), SLOT (bar()));
</code>
 
Beginners might think that we're connecting to obj1's bar() slot, when we actually are connecting to <code inline>this</code>.
 
Always specify the full types of the arguments, ''i.e.'' <code inline>const QString &</code> instead of <code inline>QString</code>, 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.
 


'''Note:''' Right now, some recommendations are different from Qt/Qt Creator Coding style, see https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
'''Note:''' Right now, some recommendations are different from Qt/Qt Creator Coding style, see https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html

Latest revision as of 16:21, 20 November 2024

This page is part of the Qt Writing Guidelines.

Qt examples follows the Qt Project's QUIP policy system.

In particular, QUIP-13 specifies the construction of the example, how to name the files, and other conventions that examples should follow.

Additionally, here are wiki pages that clarify or extend the official QUIP, by giving tips and hints for examples and its documentation.

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

Order the #include declaration 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 use the .h name (<math.h>, not <cmath>) because the new name isn't supported by all compilers

Note: Right now, some recommendations are different from Qt/Qt Creator Coding style, see https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html