Coding Standards: Difference between revisions

From ParaQ Wiki
Jump to navigationJump to search
No edit summary
No edit summary
 
(16 intermediate revisions by 4 users not shown)
Line 1: Line 1:
==Style==
== Style ==


We'll adhere to VTK coding standards except where noted here.
All code will follow the [http://www.vtk.org/Wiki/VTK_Coding_Standards VTK coding standards], with the following exceptions:


* Qt derived classes will follow Qt style for member functions.  We don't want to mix two styles in one class (Qt virtual overloads & VTK style).
* ParaQ classes (and thus, ParaQ files) will begin with "pq" instead of "vtk".
* Avoid multiple inheritance of Qt & VTK classes.  Style in such classes would be mixed.  Besides, object management is not compatible (VTK's A::New, a->Delete  vs.  Qt's new A(), nothing).
* ParaQ classes that derive from Qt classes will follow the Qt style for '''member functions only''': use camel-case with the first character lower-caseExamples: value(), mySignal(), myLittleSlot()Rationale: mixing the Qt and VTK styles was judged ugly and confusing by developers.
* Member variables will follow VTK style.  In contrast, Qt headers do one of two things: use '_' prefix to prevent collisions with get methods of the same name, hide all data in an internals class/struct.  Using the VTK style will lead to more readable code.
* All other style decisions (such as naming member variables) will follow VTK.
 
== Source Documentation ==


* Use [http://www.doxygen.org Doxygen] style tags to comment source code.
* At a minimum, each class should have a description that includes its place within the overall design and its relationships (if any) with other classes.
* At a minimum, all public members of a class should be documented with Doxygen "brief" descriptions.
* Feel free to provide additional documentation beyond the minimums - there are many useful tags available, see the [http://www.stack.nl/~dimitri/doxygen/manual.html Doxygen Manual].  A couple of favorites are "\todo" and "\deprecated", which can help considerably in eliminating orphaned code.


Here's an example class
== Sample Class ==


  /// Widget that paints a property
  /// Widget that paints a property
Line 32: Line 38:
  };
  };


==Comments==
== Testing ==
* Qt Widgets should have a name assigned whenever possible.  Although names are no longer strictly required for the test framework to function, assigning explicit names will improve the longetivity of a recorded test.  This is because the algorithm that assigns unique names is more likely to be affected by code changes than an explicit name.
 
== Qt Resources ==
 
When creating Qt resource collection (.qrc) files, '''do not''' use the alias mechanism, to change the "path" to a resource.  Consider the following example:
 
<pre>
<RCC>
  <qresource prefix="/pqWidgets" >
      <file alias="pqFoo.png">Resources/pqFoo.png</file>
  </qresource>
</RCC>
</pre>
 
In this case, the file is in a subdirectory "Resources" relative to the .qrc file.  With the given prefix, the path to this resource would be ":/pqWidgets/Resources/pqFoo.png".  However, an alias has been assigned, so that the resource can be accessed using ":/pqWidgets/pqFoo.png", which is cleaner.  Unfortunately, problems will arise if this resource collection is used in a Qt Designer (.ui) file.  The resources will appear to function correctly in Qt Designer, but the code generated by uic when the .ui file is compiled will reference the unaliased path to the resource (":/pqWidgets/Resources/pqFoo.png"), and will quietly fail at runtime, since the aliased path is the only valid path.
 
A better solution in this case is to put the .qrc file in the same directory as the corresponding resources, so their filesystem paths match the desired resource paths:


Historically, most VTK-style source documentation (.NAME, .SECTION, Description:, etc) has been converted into [[http://www.doxygen.org Doxygen]] compatible tags, then the source docs have been generated by Doxygen. Some projects (vtkSNL, CMake) have been using Doxygen tags directly. To capitalize on the popularity and features offered by Doxygen, all ParaQ-related source docs must use Doxygen tagsAt a minimum, all public interfaces should be documented with Doxygen "brief" descriptions, but there are many useful tags available, see the [[http://www.stack.nl/~dimitri/doxygen/manual.html Doxygen Manual]].  A couple of favorites are "\todo" and "\deprecated", which can help considerably in eliminating orphaned code.
<pre>
<RCC>
  <qresource prefix="/pqWidgets" >
      <file>pqFoo.png</file>
  </qresource>
</RCC>
</pre>
 
With this arrangement, the paths produced by uic will be correct.
 
== Qt Designer ==
 
When creating forms using Qt Designer, ensure that you set the following fields for all (applicable) widgets:
 
* objectName - Setting a logical, descriptive name here will ensure that recorded regression tests continue to play-back correctly as new widgets are added to the form.
* windowTitle - All top level widgets and dialogs should have a window title.
* toolTip - Set a short (a few words) human-readable description of what the widget does. Since widgets are usually labelled, make sure you aren't just repeating the label - provide additional information and tell what the widget '''does''', not what it '''is'''. Each word in the tooltip should be capitalized (ie. "Do Something" instead of "Do something").
* statusTip - Describe what the widget does in more detail, using one-or-two sentences with correct punctuation.
* whatsThis - Document what the widget is used for and how to use it. Rich text can be used. The tip can be one-or-two paragraphs or one sentence.
 
Use the following list of guidelines to determine if a widget needs a property filled in.
* All widgets need an objectName.
* All tool buttons and menu items need a toolTip.
* Most input widgets should use a statusTip. Input widgets in dialogs and pup up windows should not use a statusTip (since the status bar is in the main window). All tool buttons and menu items need a statusTip.
* All input forms should have whatsThis tips. This includes dialogs and pop up windows. The whatsThis tips within a form should compliment each other (ie. mention other related widgets).
 
The layout of widgets within a form should be consistent for the application. The object inspector pages should have a layout margin of 5 and spacing of 5 to minimize space. Dialogs and pop up windows should use a layout margin of 9 and spacing of 6 (which is the designer default).
 
== Other Useful Tidbits ==
* Avoid multiple inheritance of Qt & VTK classesStyle in such classes would be mixed.  Besides, object management is not compatible (VTK's A::New, a->Delete  vs.  Qt's new A(), nothing).
* Turn on CMake option VTK_DEBUG_LEAKS.
* Whenever a Qt class has a member variable that is a VTK object, the member must be a smart pointer. eg:
  class pqMyQtClass : public QObject
    {
    ....
    vtkSmartPointer<vtkSMProxy> Member;  // correct.
    vtkSMProxy* WrongMember;            // Incorrect, unless exra care is taken to update the reference count.
    };
* The one who ''creates'', is the one who ''destroys'': That the same class that call a vtkClassName::New() should be the one to call vtkClassName::Delete() unless it clearly states so, eg '''vtkSMProxyManager::NewProxy'''.

Latest revision as of 12:10, 11 July 2006

Style

All code will follow the VTK coding standards, with the following exceptions:

  • ParaQ classes (and thus, ParaQ files) will begin with "pq" instead of "vtk".
  • ParaQ classes that derive from Qt classes will follow the Qt style for member functions only: use camel-case with the first character lower-case. Examples: value(), mySignal(), myLittleSlot(). Rationale: mixing the Qt and VTK styles was judged ugly and confusing by developers.
  • All other style decisions (such as naming member variables) will follow VTK.

Source Documentation

  • Use Doxygen style tags to comment source code.
  • At a minimum, each class should have a description that includes its place within the overall design and its relationships (if any) with other classes.
  • At a minimum, all public members of a class should be documented with Doxygen "brief" descriptions.
  • Feel free to provide additional documentation beyond the minimums - there are many useful tags available, see the Doxygen Manual. A couple of favorites are "\todo" and "\deprecated", which can help considerably in eliminating orphaned code.

Sample Class

/// Widget that paints a property
class pqMyWidget : public QWidget
{
  Q_OBJECT
  Q_PROPERTY(QString property READ property WRITE setProperty)
  
public:
  pqMyWidget(QWidget* parent);
  ~pqMyWidget();

  /// overloaded paint event to paint property
  virtual bool paintEvent(QPaintEvent* e);

  /// get property
  QString property() const;
  /// set property
  void setProperty(QString s);

protected:
  QString Property;
};

Testing

  • Qt Widgets should have a name assigned whenever possible. Although names are no longer strictly required for the test framework to function, assigning explicit names will improve the longetivity of a recorded test. This is because the algorithm that assigns unique names is more likely to be affected by code changes than an explicit name.

Qt Resources

When creating Qt resource collection (.qrc) files, do not use the alias mechanism, to change the "path" to a resource. Consider the following example:

<RCC>
   <qresource prefix="/pqWidgets" >
      <file alias="pqFoo.png">Resources/pqFoo.png</file>
   </qresource>
</RCC>

In this case, the file is in a subdirectory "Resources" relative to the .qrc file. With the given prefix, the path to this resource would be ":/pqWidgets/Resources/pqFoo.png". However, an alias has been assigned, so that the resource can be accessed using ":/pqWidgets/pqFoo.png", which is cleaner. Unfortunately, problems will arise if this resource collection is used in a Qt Designer (.ui) file. The resources will appear to function correctly in Qt Designer, but the code generated by uic when the .ui file is compiled will reference the unaliased path to the resource (":/pqWidgets/Resources/pqFoo.png"), and will quietly fail at runtime, since the aliased path is the only valid path.

A better solution in this case is to put the .qrc file in the same directory as the corresponding resources, so their filesystem paths match the desired resource paths:

<RCC>
   <qresource prefix="/pqWidgets" >
      <file>pqFoo.png</file>
   </qresource>
</RCC>

With this arrangement, the paths produced by uic will be correct.

Qt Designer

When creating forms using Qt Designer, ensure that you set the following fields for all (applicable) widgets:

  • objectName - Setting a logical, descriptive name here will ensure that recorded regression tests continue to play-back correctly as new widgets are added to the form.
  • windowTitle - All top level widgets and dialogs should have a window title.
  • toolTip - Set a short (a few words) human-readable description of what the widget does. Since widgets are usually labelled, make sure you aren't just repeating the label - provide additional information and tell what the widget does, not what it is. Each word in the tooltip should be capitalized (ie. "Do Something" instead of "Do something").
  • statusTip - Describe what the widget does in more detail, using one-or-two sentences with correct punctuation.
  • whatsThis - Document what the widget is used for and how to use it. Rich text can be used. The tip can be one-or-two paragraphs or one sentence.

Use the following list of guidelines to determine if a widget needs a property filled in.

  • All widgets need an objectName.
  • All tool buttons and menu items need a toolTip.
  • Most input widgets should use a statusTip. Input widgets in dialogs and pup up windows should not use a statusTip (since the status bar is in the main window). All tool buttons and menu items need a statusTip.
  • All input forms should have whatsThis tips. This includes dialogs and pop up windows. The whatsThis tips within a form should compliment each other (ie. mention other related widgets).

The layout of widgets within a form should be consistent for the application. The object inspector pages should have a layout margin of 5 and spacing of 5 to minimize space. Dialogs and pop up windows should use a layout margin of 9 and spacing of 6 (which is the designer default).

Other Useful Tidbits

  • Avoid multiple inheritance of Qt & VTK classes. Style in such classes would be mixed. Besides, object management is not compatible (VTK's A::New, a->Delete vs. Qt's new A(), nothing).
  • Turn on CMake option VTK_DEBUG_LEAKS.
  • Whenever a Qt class has a member variable that is a VTK object, the member must be a smart pointer. eg:
 class pqMyQtClass : public QObject
   {
   ....
   vtkSmartPointer<vtkSMProxy> Member;   // correct.
   vtkSMProxy* WrongMember;            // Incorrect, unless exra care is taken to update the reference count.
   };
  • The one who creates, is the one who destroys: That the same class that call a vtkClassName::New() should be the one to call vtkClassName::Delete() unless it clearly states so, eg vtkSMProxyManager::NewProxy.