OverviewQtilities provides a powerful implementation of the subject-observer pattern and an easy way to display the contents of such an observer context. The main class to use when viewing observers is Qtilities::CoreGui::ObserverWidget. The observer widget is able to show the contents as a tree widget or as a table widget and the user can specify the view which is required as a parameter in the constructor, or change the view at runtime. Observers provide hints to item views which specify how the context must be shown, what actions can be performed on the items in the context, what the access mode of the observer is etc. This article will show how to use the observer widget class and how it is linked with the observer context it is displaying. Note that the Table of contents:
|
|
To create an observer widget is very simple, first we need an observer context and then we can initialize the observer widget for that observer context. We will use the same tree structure that was introduced in the Building Trees article in here. Now lets look at an example where we construct that tree structure and create an observer widget for it.
The above application produces the following widget:
Observer widgets are by default initialized as tree widgets. However we can decide we want a table view rather than a tree view by passing the correct parameter in the observer widget constructor. For example:
The resulting widget looks like this:
For flat observer structures the above widget would be sufficient, however for hierarchical tree structures such as the example structure we are using, this is not going to work. The user must be able to push down into an observer and push up the tree as well. In order to do this, we need to add actions for to the observer widget which the user can then use to perform these tasks. We use Qtilities::Core::ObserverHints to do this. Observer hints are described in detail later in this article in the Observer hints: Telling item views how they should show an observer context section. For now we don't go into the details.
These additions will result in the observer widget shown below:
A third action, specified by Qtilities::Core::ObserverHints::ActionSwitchView was also added to our example. When this action is present the user can switch the type of view at runtime. Lastly, observer widgets automatically provide actions to expand or collapse tree structures when the observer widget is in the tree mode. In the above widget they are not shown since the observer widget is in table mode.
The observer widget class provides functions which makes it easy to interact with selected objects in the item view presented to the user. It is possible to retrieve selected objects at any time using the Qtilities::CoreGui::ObserverWidget::selectedObjects() function. The Qtilities::CoreGui::ObserverWidget::selectedObjectsChanged() signal is emitted when the active objects changes and the Qtilities::CoreGui::ObserverWidget::observerContextChanged() signal is emitted as soon as the observer context in the widget change. This would happen for example when the user push down into a tree hierarchy.
Observers can provide display hints to any observer widgets in which it is displayed. The available hints are defined in the form of the Qtilities::Core::ObserverHints class and are explained in this section. Observer widgets automatically follow the hints of the widget's current observer context if the context provides hints. It is however possible to turn this feature off using the Qtilities::CoreGui::ObserverWidget::toggleUseObserverHints() function and then set the hints explicitly using the Qtilities::CoreGui::ObserverWidget::setActiveHints() function as shown in the above example.
Observers does not automatically provide hints and the Qtilities::Core::Observer::useDisplayHints() function must be called on the observer after it is constructed and before any subjects are attached to it. Qtilities::CoreGui::TreeNode on the other hand calls this function in its constructor.
The hints are interpreted when the observer widget is initialized, thus they must be set before the initialization function call on the observer widget. The rest of this section will explore the different hints.
Action hints are hints which tells observer widgets which actions must be available for a specific context. The observer widget class implements the Qtilities::CoreGui::Interfaces::IActionProvider interface through which it provides all the actions for a specific observer context. Actions are created as needed during initialization calls on the observer widget, thus if an observer context does not provide any action hints, no actions will be created and the interface will provide an empty list of actions. The possible action hints are defined in the Qtilities::Core::ObserverHints::ActionItem enumeration.
If is possible to control if objects can be selected in the observer widget. For more information see Qtilities::Core::ObserverHints::setItemSelectionControlHint() and Qtilities::Core::ObserverHints::itemSelectionControlHint().
In the examples thus far we only showed the item view (table or tree view) and for table views an navigation bar and an action toolbar at the top of the widget. It is possible to control this through the Qtilities::Core::ObserverHints::setDisplayFlagsHint() and Qtilities::Core::ObserverHints::displayFlagsHint() functions as shown already.
Lets modify our example to also display a Qtilities::CoreGui::ObjectPropertyBrowser through which users can edit Q_PROPERTY properties of the selected object.
These additions will result in the observer widget shown below:
The Qtilities::Core::ObserverHints::setNamingControlHint() function can be called to provide a hint which will determine if object names should be editable or not. The Qtilities::CoreGui::NamingPolicyFilter was created to help with name management inside an observer context and when a context with a naming policy filter installed is set as the observer context of an observer widget, the naming policy filter will automatically be used to help with name management by providing a Qtilities::CoreGui::NamingPolicyDelegate delegate which is used during the editing of object names.
Lets adapt our example by installing a naming policy filter set to use unique names to our top level observer, and we set the naming control hint on the observer to editable names.
The image below shows what happens when we want to change an object name inside the top level observer context to the name of an existing object.
An useful feature of the Qtilities::Core::Observer class is that it supports the grouping of objects within the context into categories. Lets change our example again by adding intended categories for objects that we attach to nodeB
.
These changes will result in the observer widget shown below (in tree mode):
In table view mode the categories are shown in an extra column. To enable this column we need to specify the correct column hint:
Columns are described in more detail in the Control over displayed columns section.
It is possible to filter the displayed categories as well. As with all the other display hints we can either set the filtering parameters on the Observer itself, or on the display hints of the ObserverWidget when we don't use observer hints in the widget. In our example thus far we are using custom hints, thus we set the filtering parameters on the activeHints()
of the ObserverWidget (which points to our custom hints).
After adding the category filter, the observer widget looks this:
In the same way that observer widgets integrate with naming policy filters, automatic integration with activity policy filters also happens when an observer context displayed has a Qtilities::Core::ActivityPolicyFilter installed. Observers can provide two hints related to activity control: a hint indicating how activity must be displayed (see Qtilities::Core::ObserverHints::ActivityDisplay) and a hint indicating how activity changes should happen (see Qtilities::Core::ObserverHints::ActivityControl).
Lets adapt our example by installing an activity policy filter on rootNode
and nodeA
using the convenience functions of Qtilities::CoreGui::TreeNode.
After adding the activity filter, the observer widget will look like this:
The Qtilities::Core::ActivityPolicyFilter class also provides other activity management options which allows control over the activity of subjects within an observer context. It is up to the reader to explore the other activity control options.
The Qtilities::Core::ObserverHints::ItemViewColumn hint provides control over pre-defined columns that can be shown in the observer widget. Lets enable all columns and look at the resulting observer widget.
After setting the item view column hint, the observer widget will look like this:
It is easy to extend an observer widget with custom columns. The Qtilities::Examples::Clipboard example demonstrates this. Also see the following section of this article: The models doing the work behind the scenes.
Observer access modes provides the ability to control the changes which can be made to an observer and are defined in the Qtilities::Core::Observer::AccessMode enumeration. Observers provide the ability to specify access modes on a global scope or on a category level through the Qtilities::Core::Observer::setAccessModeScope() function. Again, lets modify our example by setting the access mode of the observers in the example (Note that we do this after the attachments for our example).
The resulting observer widget is shown below. It must be noted that the ColumnAccess item view column must be provided by the observer context:
The table mode's hierarchy navigation bar goes a step further and colors the name of a read only context in red as a direct indication that the context is read only.
Observer widgets can automatically show a search box widget embedded at the bottom of the widget when the active hints specifies that finding items is supported.
The resulting widget will display a find action, and when clicked it will provide an integrated Qtilities::CoreGui::SearchBoxWidget to the user.
The Qtilities object manager is able to manage global active objects, for more information see Global object activity management. The observer widget class can integrate with the object manager and the meta type which is used for a specific observer widget can be set using the Qtilities::CoreGui::ObserverWidget::setGlobalMetaType() function.
The ObserverWidget class provides the Qtilities::CoreGui::ObserverWidget::writeSettings() and Qtilities::CoreGui::ObserverWidget::readSettings() functions which can be used to store information about an observer widget.
Qtilities::CoreGui::ObserverWidget::globalMetaType() is used as the Widget_Name
field in the group where the settings are stored. Observer widget classes are connected to the Qtilities::Core::QtilitiesCoreApplication::settingsUpdateRequest() signal by default and responds to settings update requests for the specific global meta type. See the function documentation for more details on this topic. See the ClipboardExample
in the QtilitiesExamples
project for a demonstration of how observer widget settings are managed.
For more information on this see Configuration settings storage in Qtilities.
Depending on the mode in which the observer widget is, it uses data models designed specifically for the observer implementation. In tree mode, the model doing the work is Qtilities::CoreGui::ObserverTreeModel, and in table mode Qtilities::CoreGui::ObserverTableModel is used.
It is possible to extend models pretty easily. Again, see the ClipboardExample
in the QtilitiesExamples
project for more information, more specifically see the Qtilities::Examples::Clipboard::ExtendedObserverTableModel and Qtilities::Examples::Clipboard::ExtendedObserverTreeModel classes.
Qtilities : Reference Documentation | Back to top |
Copyright © 2009-2013, Jaco Naudé
|