Qt6/Example-Guideline: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(Recommend /W4 for MSVC, /Wall produces a lot of warning about C++98 compatibility that we don't care about.)
 
(66 intermediate revisions by 11 users not shown)
Line 1: Line 1:
''When creating or updating Qt examples, developer should consider the best practises and guidelines listed in this document.
[[Category:Developing Qt::Examples]]
''
When creating or updating Qt examples, developer should consider the best practises and guidelines listed in this document.


== Evaluate if the example is meaningful or should it be removed/merged ==
See also: [[Documentation Style for Examples]].


==Evaluate if the example is meaningful or should it be removed/merged==
'''MANDATORY'''
'''MANDATORY'''
* Check if there are similar examples for the same topic and consider if both are really needed or should the other one be merged with the other.
* Check also documentation on the topic and if that includes inline code snippet that would be adequate instead of complete example.


== No C++ or qml warnings ==
*Check if there are similar examples for the same topic and consider if both are really needed or should they be merged.
*Check also documentation on the topic and if that includes inline code snippet that would be adequate instead of complete example.
*Ensure the example is included in the related examples-manifest.xml file and shown part of documentation. See https://doc.qt.io/qt-6/26-qdoc-configuration-example-manifest-files.html
**If the example is not shown, consider moving it under tests/manual/examples.
**Do not add examples to the examples-manifest.xml file that don't meet this guideline criteria.


==Formatting==
'''RECOMMENDED'''
*C++: Use clang-format for C++ files
*QML: Use qmlformat -i -n to normalize formatting and order of QML files
==No C++ or qml warnings==
'''MANDATORY'''
'''MANDATORY'''
* Example's C++ code should be by minimum compiled with the same compiler warning flags as Qt.
* Use qmllint for qml code: https://doc-snapshots.qt.io/qt6-dev/qtquick-tool-qmllint.html
* Enable compiler warnings and check if the reported issues are fixable with meaningful effort. 


*Example's C++ code should be by minimum compiled with the same compiler warning flags as Qt.
*Use qmllint for qml code: https://doc.qt.io/qt-6/qtquick-tool-qmllint.html
*Enable compiler warnings and check if the reported issues are fixable with meaningful effort.


<br>
'''RECOMMENDED'''
'''RECOMMENDED'''
<br>
<br>
Consider also the compilation with the more strict warning flags and fix the found issues.
Consider also compiling with the more strict warning flags and fix possible issues they reveal especially if these are in the example code.
<br>
GCC
* Use -Wall and consider -Wextra parameter: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html


Clang
;GCC:Use -Wall and consider -Wextra parameter: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
* Use -Weverything compiler parameter: https://clang.llvm.org/docs/UsersManual.html#diagnostics-enable-everything
;Clang:Use -Weverything compiler parameter: https://clang.llvm.org/docs/UsersManual.html#diagnostics-enable-everything
;Visual Studio:Use /W4 compiler parameter: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level


Visual Studio
==Qt6 best practises and changes==
* Use /Wall compiler parameter: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level
'''MANDATORY'''


== Qt6 best practises and changes ==
*Check the porting guide for Qt6: https://doc.qt.io/qt-6/portingguide.html
<br>
*Ensure the example complies with the Qt 6 porting guides for each module the example is using: https://doc.qt.io/qt-6/modulechanges.html
*Check the best practises for QtQML & QtQuick: https://doc-snapshots.qt.io/qt6-dev/qtquick-bestpractices.html
*Do not use versions in QML import statements. This is usally a left-over from Qt 5.
*Place .qml and .js files in the same directory as the qt_add_qml_module. Otherwise their implicit import is not the module they belong to.
 
==Leveraging C++17==
'''MANDATORY'''
'''MANDATORY'''
<br>
* Check the porting guide for Qt6: https://doc.qt.io/qt-6/portingguide.html
* Ensure the example complies with the Qt 6 porting guides for each module the example is using: https://doc.qt.io/qt-6/modulechanges.html
* Check the best practises for QtQML & QtQuick: https://doc-snapshots.qt.io/qt6-dev/qtquick-bestpractices.html
* Do not use versions in QML import statements. This is usally a left-over from Qt 5.


== Leveraging C++17 ==
*Follow Qt Coding conventions: https://wiki.qt.io/Coding_Conventions
*Use clazy plugin (comes also with Qt Creator): https://www.qt.io/blog/porting-from-qt-5-to-qt-6-using-clazy-checks
 
<br>
<br>
'''RECOMMENDED'''
'''RECOMMENDED'''
<br>
* Prefer signal/slot connection with lambdas: https://doc.qt.io/qt-6/signalsandslots.html
* Check Qt Coding conventions: https://wiki.qt.io/Coding_Conventions
* Consider using clazy plugin (comes also with Qt Creator): https://www.qt.io/blog/porting-from-qt-5-to-qt-6-using-clazy-checks


== Naming the example, categorisation and adding keywords ==
*Prefer making signal/slot connections using functor syntax over the string-based versions: https://doc.qt.io/qt-6/signalsandslots.html
<br>
**For short (~5 lines of code) slots, consider using signal/slot connection with lambdas
'''MANDATORY'''
**Longer slot should be member functions
<br>
 
==Naming the example==
 
*Don't add the Qt module name or the word "Example" to the example name. e.g. QtWidgets Application Example → Text editor application
**Exception: If it's really not possible to clearly describe the example's functionality without using (part of) the module name, that can still be done (e.g. "Simple CoAP Client Example" from the Qt CoAP module).
 
==Categorisation==


* Don't add Qt module name or "Example" word to the example name. e.g. QtWidgets Application Example → Text editor application
*Add example application to a suitable category using the <code>\examplecategory</code> macro, for example:
** Note: If the part of the module name really needs to be used due to clearly describing functionality, that can still be done (e.g. Simple CoAP Client Example from Qt CoAP module)
* Add example application to correct category, for instance by adding '\meta category {Graphics & UI}' below '\examples'


   \example My Example
   \example My Graphical Application
   \meta category {My Category}
   \examplecategory {Graphics}


Will end up as  
This will end up as  
   <categories>  
   <meta>  
     <category>My Category</category>  
     <entry name="category">Graphics</entry>  
   </categories>
   </meta>


in the <example> section of the respective examples-manifest.xml file.
in the <example> section of the relevant examples-manifest.xml file.
<br>
<br>
For further details see: https://codereview.qt-project.org/c/qt/qttools/+/447246


<br>
*Example should typically belong to only one category. Consider what's the most essential feature that the example is teaching and pick the category accordingly.
**If there isn't an appropriate category for the example, it can be left out. Such examples will be listed under category 'Other'.
**In the description and tags (see below) you can add more information to make finding the example easy.
 
'''Acceptable categories'''
 
*Application Examples
**Most prominently showed examples
**Complete applications with a (hypothetical) use case
**''Please check with documentation team before adding examples to this category''
*Desktop
**Examples showing a typical traditional UI used with mouse
**Desktop-only use cases (QtActiveQt, Qt UI Tools, Qt Assistant, System Tray ...)
*Mobile
**Examples showing a Touch UI that adapts to different screen sizes
**Should feel native on Android and/or iOS
**Mobile-only use cases (e.g. Qt Android Notifier)
*Embedded
**Examples showing a one screen size, touch based UI
**Custom, not native look&feel
**Embedded-only use cases (Qt Wayland Compositor, Qt Virtual Keyboard)
*Graphics & Multimedia
**Qt Quick3D, Qt Multimedia
*Data Visualization & 3D
**Qt Data Visualization, Qt Charts, Qt Graphs, Qt 3D, Qt Quick 3D
*Data Processing & I/O
**XML, IO Device, etc.
*Connectivity
**Bluetooth, IPC, MQTT...
*Networking
**HTTP, TCP, and UDP
*Positioning & Location
*User Interface Components
**Generic Qt Quick, Qt Widgets components that do not fit the other areas
*Web Technologies
**WebEngine, WebView, WebChannel
 
'''RECOMMENDED'''
'''RECOMMENDED'''
<br>
* Confirm that the example shows up in Qt Creator welcome screen.
* Check that the example description text shown in Creator contains the right keywords for users to find it.
* Add appropriate tags to the example, for instance by adding '\meta tags {tag1,tag2}' below '\examples'.
* Tags are used to set additional keywords for the example which makes it easier to search in Qt Creator example view
** Don't add redundant information as tags which is already part of the category, example name or description
** Don't add platform information in the tags


== Visual Style ==
*Confirm that the example shows up in Qt Creator's Welcome screen.
<br>
*Check that the example description text shown in Creator contains the right keywords for users to find it.
*Add appropriate tags to the example; see below.
 
==Example metadata==
 
=== Tags ===
*Tags are used to set additional keywords for the example.
*This makes it easier to find them by searching in Qt Creator's example view
*Common tags are for the UI stack (widgets, quick), and the 'main' module of the example.
**Note that QDoc automatically adds tags for the Qt module, if not already set manually.
*Don't add, as tags, information which is already part of the category, example name or description.
*Don't add platform information in the tags
 
Example:
 
  \example My Example
  \meta tag {quick,network}
 
=== Highlighting ===
 
In Qt Creator, examples inside a category are shown in alphabetical order . One can 'highlight' examples though, so that they are shown first. We should aim for highlighting 5-12 examples per category.
 
To mark an example as highlighted, you add its name, prefixed with a module name and a slash to manifestmeta.highlighted.names  of the respective .qdocconf file:
 
  manifestmeta.highlighted.names = "QtDoc/Calqlatr" \
                                    "QtDoc/Coffee Machine" \
                                    "QtDoc/Dice"
 
Simple wildcard matching is supported; by using * at the end, it's possible to match multiple examples with a single string.
 
==Visual Style==
'''MANDATORY'''
'''MANDATORY'''
* Screen shots taken with high dpi resolution, minimum image size 440x320.
 
** Note: Images can be larger but should follow either 4:3 or 5:4 aspect ratio. Take meaningful image that gives an idea what the example is about.
*Screen shots taken with high dpi resolution, minimum image size 440x320.
* Icons should be suitable for high dpi screen with minimum size of 64x64.
**Note: Images can be larger but should follow either 4:3 or 5:4 aspect ratio. Take meaningful image that gives an idea what the example is about.
*Icons should be suitable for high dpi screen with minimum size of 64x64.
*Image assets should have the minimum size rquired. See for instance [https://doc-snapshots.qt.io/qtcreator-extending/qtcreator-documentation.html#optimizing-images Optimizing Images] for advice.
 
<br>
<br>
'''RECOMMENDED'''
'''RECOMMENDED'''
<br>
* Consider using Qt Quick over Qt Widgets but remember also dependency restrictions with module api examples.
* Create example's qml part to be Qt Design Studio compatible.
** Define purely declarative qml files with .ui.qml file extension.
** Test the project also in Qt Design Studio.
* Layouts should be tested on multiple platforms (macOS, Linux, Windows, iOS, Android, Embedded Linux (EGLFS) with full HD target screen resolution.


== Build System ==
*Consider using Qt Quick over Qt Widgets but remember also dependency restrictions with module api examples.
<br>
*Create example's qml part to be compatible with Qt Design Studio.
**Define purely declarative qml files with .ui.qml file extension.
**Test the project also in Qt Design Studio.
*Layouts should be tested on multiple platforms (macOS, Linux, Windows, iOS, Android, Embedded Linux / EGLFS) with full HD target screen resolution.
 
==Build System==
'''MANDATORY'''
'''MANDATORY'''
*Our users should be able to build with both <kbd>qmake</kbd> and CMake. Both build systems should therefore work.
*Check that the example runs without any issues when opened in the Qt Creator welcome screen, on all platforms. If additional steps are necessary, or examples only run on some platforms, make sure that this is prominently stated in the example's documentation.
*CMake
**Do not use the <kbd>find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)</kbd> pattern that is created for instance in <kbd>CMakeLists.txt</kbd> files created by Qt Creator wizards. This pattern is for keeping compatibility with Qt 5, which we don't strive for with Qt 6 examples. Use <kbd>find_package(Qt6 REQUIRED COMPONENTS Core)</kbd> instead.
**Use <kbd>qt_standard_project_setup()</kbd> rather than enabling <kbd>AUTOMOC</kbd> and <kbd>AUTOUIC</kbd> manually
**Use <kbd>PRIVATE</kbd> linkage, for example in <kbd>target_link_libraries()</kbd>
You should be able to build each example,
if its <kbd>CMakeLists.txt</kbd> and <kbd>.pro</kbd> files are correctly configured,
using either of them.
This should be possible using a standard build (with <kbd>-no-make examples</kbd>),
building from the example's source in a <kbd>git</kbd> checkout (handy for verifying your improvements).
With your build's <kbd>qtbase/bin/</kbd> in your <kbd>PATH</kbd>, for <kbd>cmake</kbd> and <kbd>qt-cmake</kbd>, first <kbd>cd</kbd> to the directory in which you want the build artefacts.
;With CMake:<kbd>qt-cmake path/to/example/dir/ && cmake --build . --parallel</kbd>
;With QMake:<kbd>qmake path/example/dir/whatever.pro && make</kbd>
<br>
<br>
* Our users should be able to build both with qmake and CMake. Both build systems should therefore work.
'''RECOMMENDED'''
* Check that the example runs without any issues when opened in Qt Creator welcome screen, on all platforms. If additional steps are necessary, or examples do only run on some platforms, make sure that is is prominently stated in the example's documentation.
* CMake
** Do not use the 'find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)' pattern that is created for instance in CMakeLists.txt files created by Qt Creator wizards. This pattern is for keeping compatibility with Qt 5, which we don't strive for with Qt 6 examples.
** Use qt_standard_project_setup() instead enabling AUTOMOC, AUTOUIC manually
** Use PRIVATE linkage
<br>
<br>
*Avoid including (re)sources from outside the example directory, as examples should be self-contained.
==Enable automated release testing==
'''RECOMMENDED'''
'''RECOMMENDED'''
<br>
<br>
* Avoid including (re)sources outside of the example directory, as examples should be self-contained.
For enabling RTA testing add unique object names for all the UI objects


== Misc ==
*https://doc.qt.io/qt-6/qobject.html#setObjectName
<br>
*https://kb.froglogic.com/squish/howto/explicitly-naming-objects/
 
==Misc==
'''MANDATORY'''
'''MANDATORY'''
<br>
 
* Do not use QT_BEGIN_NAMESPACE ... QT_END_NAMESPACE for example types. This namespace is exclusively for types in the Qt libraries.
*Do not use QT_BEGIN_NAMESPACE &hellip; QT_END_NAMESPACE for example types. These macros are exclusively to support "namespaced" builds of Qt (see [[Qt In Namespace]]) and surround declarations of types from the Qt libraries and overloads of operators that are not found by argument-dependent name lookup. If using the macros is considered too ugly, another option is to #include the respective Qt header.
 
*Verify if the example [https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples was ported to the Qt for Python project] and if exists, notify the team with a comment on https://bugreports.qt.io/browse/PYSIDE-2206 with a link to the review of your changes.

Latest revision as of 17:40, 7 December 2023

When creating or updating Qt examples, developer should consider the best practises and guidelines listed in this document.

See also: Documentation Style for Examples.

Evaluate if the example is meaningful or should it be removed/merged

MANDATORY

  • Check if there are similar examples for the same topic and consider if both are really needed or should they be merged.
  • Check also documentation on the topic and if that includes inline code snippet that would be adequate instead of complete example.
  • Ensure the example is included in the related examples-manifest.xml file and shown part of documentation. See https://doc.qt.io/qt-6/26-qdoc-configuration-example-manifest-files.html
    • If the example is not shown, consider moving it under tests/manual/examples.
    • Do not add examples to the examples-manifest.xml file that don't meet this guideline criteria.

Formatting

RECOMMENDED

  • C++: Use clang-format for C++ files
  • QML: Use qmlformat -i -n to normalize formatting and order of QML files

No C++ or qml warnings

MANDATORY

  • Example's C++ code should be by minimum compiled with the same compiler warning flags as Qt.
  • Use qmllint for qml code: https://doc.qt.io/qt-6/qtquick-tool-qmllint.html
  • Enable compiler warnings and check if the reported issues are fixable with meaningful effort.


RECOMMENDED
Consider also compiling with the more strict warning flags and fix possible issues they reveal especially if these are in the example code.

GCC
Use -Wall and consider -Wextra parameter: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Clang
Use -Weverything compiler parameter: https://clang.llvm.org/docs/UsersManual.html#diagnostics-enable-everything
Visual Studio
Use /W4 compiler parameter: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level

Qt6 best practises and changes

MANDATORY

Leveraging C++17

MANDATORY


RECOMMENDED

  • Prefer making signal/slot connections using functor syntax over the string-based versions: https://doc.qt.io/qt-6/signalsandslots.html
    • For short (~5 lines of code) slots, consider using signal/slot connection with lambdas
    • Longer slot should be member functions

Naming the example

  • Don't add the Qt module name or the word "Example" to the example name. e.g. QtWidgets Application Example → Text editor application
    • Exception: If it's really not possible to clearly describe the example's functionality without using (part of) the module name, that can still be done (e.g. "Simple CoAP Client Example" from the Qt CoAP module).

Categorisation

  • Add example application to a suitable category using the
    \examplecategory
    
    macro, for example:
 \example My Graphical Application
 \examplecategory {Graphics}

This will end up as

 <meta> 
   <entry name="category">Graphics</entry> 
 </meta>

in the <example> section of the relevant examples-manifest.xml file.

  • Example should typically belong to only one category. Consider what's the most essential feature that the example is teaching and pick the category accordingly.
    • If there isn't an appropriate category for the example, it can be left out. Such examples will be listed under category 'Other'.
    • In the description and tags (see below) you can add more information to make finding the example easy.

Acceptable categories

  • Application Examples
    • Most prominently showed examples
    • Complete applications with a (hypothetical) use case
    • Please check with documentation team before adding examples to this category
  • Desktop
    • Examples showing a typical traditional UI used with mouse
    • Desktop-only use cases (QtActiveQt, Qt UI Tools, Qt Assistant, System Tray ...)
  • Mobile
    • Examples showing a Touch UI that adapts to different screen sizes
    • Should feel native on Android and/or iOS
    • Mobile-only use cases (e.g. Qt Android Notifier)
  • Embedded
    • Examples showing a one screen size, touch based UI
    • Custom, not native look&feel
    • Embedded-only use cases (Qt Wayland Compositor, Qt Virtual Keyboard)
  • Graphics & Multimedia
    • Qt Quick3D, Qt Multimedia
  • Data Visualization & 3D
    • Qt Data Visualization, Qt Charts, Qt Graphs, Qt 3D, Qt Quick 3D
  • Data Processing & I/O
    • XML, IO Device, etc.
  • Connectivity
    • Bluetooth, IPC, MQTT...
  • Networking
    • HTTP, TCP, and UDP
  • Positioning & Location
  • User Interface Components
    • Generic Qt Quick, Qt Widgets components that do not fit the other areas
  • Web Technologies
    • WebEngine, WebView, WebChannel

RECOMMENDED

  • Confirm that the example shows up in Qt Creator's Welcome screen.
  • Check that the example description text shown in Creator contains the right keywords for users to find it.
  • Add appropriate tags to the example; see below.

Example metadata

Tags

  • Tags are used to set additional keywords for the example.
  • This makes it easier to find them by searching in Qt Creator's example view
  • Common tags are for the UI stack (widgets, quick), and the 'main' module of the example.
    • Note that QDoc automatically adds tags for the Qt module, if not already set manually.
  • Don't add, as tags, information which is already part of the category, example name or description.
  • Don't add platform information in the tags

Example:

 \example My Example
 \meta tag {quick,network}

Highlighting

In Qt Creator, examples inside a category are shown in alphabetical order . One can 'highlight' examples though, so that they are shown first. We should aim for highlighting 5-12 examples per category.

To mark an example as highlighted, you add its name, prefixed with a module name and a slash to manifestmeta.highlighted.names of the respective .qdocconf file:

  manifestmeta.highlighted.names = "QtDoc/Calqlatr" \
                                   "QtDoc/Coffee Machine" \
                                   "QtDoc/Dice"

Simple wildcard matching is supported; by using * at the end, it's possible to match multiple examples with a single string.

Visual Style

MANDATORY

  • Screen shots taken with high dpi resolution, minimum image size 440x320.
    • Note: Images can be larger but should follow either 4:3 or 5:4 aspect ratio. Take meaningful image that gives an idea what the example is about.
  • Icons should be suitable for high dpi screen with minimum size of 64x64.
  • Image assets should have the minimum size rquired. See for instance Optimizing Images for advice.


RECOMMENDED

  • Consider using Qt Quick over Qt Widgets but remember also dependency restrictions with module api examples.
  • Create example's qml part to be compatible with Qt Design Studio.
    • Define purely declarative qml files with .ui.qml file extension.
    • Test the project also in Qt Design Studio.
  • Layouts should be tested on multiple platforms (macOS, Linux, Windows, iOS, Android, Embedded Linux / EGLFS) with full HD target screen resolution.

Build System

MANDATORY

  • Our users should be able to build with both qmake and CMake. Both build systems should therefore work.
  • Check that the example runs without any issues when opened in the Qt Creator welcome screen, on all platforms. If additional steps are necessary, or examples only run on some platforms, make sure that this is prominently stated in the example's documentation.
  • CMake
    • Do not use the find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) pattern that is created for instance in CMakeLists.txt files created by Qt Creator wizards. This pattern is for keeping compatibility with Qt 5, which we don't strive for with Qt 6 examples. Use find_package(Qt6 REQUIRED COMPONENTS Core) instead.
    • Use qt_standard_project_setup() rather than enabling AUTOMOC and AUTOUIC manually
    • Use PRIVATE linkage, for example in target_link_libraries()

You should be able to build each example, if its CMakeLists.txt and .pro files are correctly configured, using either of them. This should be possible using a standard build (with -no-make examples), building from the example's source in a git checkout (handy for verifying your improvements). With your build's qtbase/bin/ in your PATH, for cmake and qt-cmake, first cd to the directory in which you want the build artefacts.

With CMake
qt-cmake path/to/example/dir/ && cmake --build . --parallel
With QMake
qmake path/example/dir/whatever.pro && make


RECOMMENDED

  • Avoid including (re)sources from outside the example directory, as examples should be self-contained.

Enable automated release testing

RECOMMENDED
For enabling RTA testing add unique object names for all the UI objects

Misc

MANDATORY

  • Do not use QT_BEGIN_NAMESPACE … QT_END_NAMESPACE for example types. These macros are exclusively to support "namespaced" builds of Qt (see Qt In Namespace) and surround declarations of types from the Qt libraries and overloads of operators that are not found by argument-dependent name lookup. If using the macros is considered too ugly, another option is to #include the respective Qt header.