Coding Standards
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.