Workspace 6.21.5
|
Base class for objects handling the connection between data objects and QWidget instances. More...
#include <Workspace/Widgets/qwidgetconnector.h>
Public Slots | |
bool | hasOutstandingDataUpdateRequests () const |
void | requestUpdateData () |
void | requestUpdateWidget () |
void | synchronizeWithData () |
Signals | |
void | dataUpdated () |
Public Member Functions | |
void | clearAllWidgetPropertyMonitors () |
WidgetPropertyMonitor & | createWidgetPropertyMonitor (const QString &propertyName) |
NamePath & | getNamePath () |
QUuid | getUuid () const |
QWidget & | getWidget () |
bool | setAdaptorFactory (const DataExecution::TypeAdaptorFactory *adaptorFactory) |
virtual void | setWidgetReadOnly (bool b) |
Static Public Member Functions | |
static QStringList | connectWidgetTree (QWidget &widget, DataExecution::Operation &forOperation) |
static QStringList | connectWidgetTree (QWidget &widget, DataExecution::Operation &forOperation, const std::function< bool(QString)> &isIgnoredGlobalName) |
static QStringList | connectWidgetTree (QWidget &widget, DataExecution::Workspace &relativeTo) |
static QStringList | connectWidgetTree (QWidget &widget, DataExecution::Workspace &relativeTo, const std::function< bool(QString)> &isIgnoredGlobalName) |
Protected Slots | |
virtual void | checkIfWidgetWantsUpdateTriggers () |
virtual void | flushChanges (bool widgetWillRemainAlive=true) |
void | madeUncommittedChange () |
Protected Member Functions | |
QWidgetConnector (QWidget &widget, const NamePath &namePath, bool directWidgetUpdates=false) | |
~QWidgetConnector () override | |
void | clearUncommittedChanges () |
template<typename T > | |
void | commitData (const T &value) |
bool | haveUncommittedChanges () const |
void | setWantUpdateTriggers (bool b) |
QWidgetConnector instances must be created in the GUI thread, just like any QWidget must be.
|
protected |
widget | The widget to connect to the workspace data. |
namePath | The name path of the input or output whose data should be connected to the widget. If the input/output has hierarchical data associated with it (eg as an object group), the name path also specifies which data object within the hierarchy the connector is associated with. Note that namePath must be valid (ie returns true from its isValid() function). N.B. You should not assume the data type of the namePath to be the type used by this connector in the constructor. NamePaths for adapted types can be passed to this constructor that will be adapted to the correct DataObject type during calls to updateData() and updateWidget(). Eg. If your connector is for type int, don't assume WS_ASSERT_RUNTIME(namePath.getDataObject()->isType<int>()) is true during the constructor. |
directWidgetUpdates | Some widget connectors have the ability to perform compute-intensive parts in the execution thread and lightweight parts in the widget's thread. By setting directWidgetUpdate to true , subclasses can indicate that they will manage the thread synchronization themselves and that they can have their updateWidget() functions called from the execution thread. Note that updateWidget() can be called from the execution thread or from the widget's thread in this arrangement, so the subclass should take care to handle both safely. The default for this parameter is false and the vast majority of subclasses will use this default value. One example where it might be true is an image rendering widget where the image is rendered off-screen to an image first in the execution thread, then the image is copied to the widget in the widget's thread. |
The connector is made a child of widget, so if/when the widget is destroyed, the connector will be destroyed too. Qt's parent-child handling ensures that children are destroyed before their parents, so the connector will always be destroyed before the widget.
|
overrideprotecteddefault |
|
protectedvirtualslot |
void clearAllWidgetPropertyMonitors | ( | ) |
|
protected |
This function does not normally need to be called. It can be called if the subclass decides that it wants to discard any uncommitted changes it has notified the base class about. The more common case where it is called, however, is in an updateWidget() reimplementation immediately after the widget has been updated. The updating of the widget might trigger a signal which results in the madeUncommittedChange() being called, but since the widget was just updated, there is no uncommitted change, so calling clearUncommittedChanges() restores the correct state. Connectors that never call madeUncommittedChange() should not ever need to call clearUncommittedChanges().
|
inlineprotected |
This function is specifically designed to be called in situations where the underlying data needs to be updated with a value, but the connector might not live long enough to apply the change. This situation often arises for connectors that do delayed data commits, such as those associated with text entry widgets. In such cases, the connector might need to apply any uncommitted changes before the widget is destroyed, but the execution threads might not allow a change to be committed immediately. If the data type is assignable, this function can be called with the value to be committed to the data and the connector can then be destroyed. The change will be applied to the data at the earliest opportunity and this can be after the connector is gone, since no references to it or its widget are used to implement the delayed commit (a copy is taken of the value parameter and stored internally if necessary).
|
static |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
widget | This widget and all its children will be visited and for any that have the appropriate property information, an attempt will be made to connect them to the specified operation's inputs and outputs. |
forOperation | All connector information will be treated as relative to this specific operation. Because it is an operation and not a workspace, the connectors can will typically refer to input or output names rather than global names. |
This function should only be called if op is not a Workspace. It is typically used to connect a widget hierarchy which was loaded from a .ui file meant for showing a particular type of operation.
|
static |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
widget | This widget and all its children will be visited and for any that have the appropriate property information, an attempt will be made to connect them to the specified operation's inputs and outputs. |
forOperation | All connector information will be treated as relative to this specific operation. Because it is an operation and not a workspace, the connectors can will typically refer to input or output names rather than global names. |
isIgnoredGlobalName | Function that checks if a global name is ignored by the caller. When a global name is ignored, the connection between the widget and the workspace will not be made. |
This function should only be called if op is not a Workspace. It is typically used to connect a widget hierarchy which was loaded from a .ui file meant for showing a particular type of operation.
|
static |
widget | This widget and all its children will be visited and for any that have the appropriate property information, an attempt will be made to connect them to the specified workspace data. |
relativeTo | All connector information stored in the widgets specify paths to operations relative to some common workspace. The relativeTo workspace will serve as this common workspace. |
|
static |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
widget | This widget and all its children will be visited and for any that have the appropriate property information, an attempt will be made to connect them to the specified workspace data. |
relativeTo | All connector information stored in the widgets specify paths to operations relative to some common workspace. The relativeTo workspace will serve as this common workspace. |
isIgnoredGlobalName | Function that checks if a global name is ignored by the caller. When a global name is ignored, the connection between the widget and the workspace will not be made. |
WidgetPropertyMonitor & createWidgetPropertyMonitor | ( | const QString & | propertyName | ) |
propertyName | Name of the widget property to monitor. |
|
signal |
|
protectedvirtualslot |
widgetWillRemainAlive | If widgetWillRemainAlive is true , then the subclass implementation is allowed to access the widget with which this connector is associated. If it is false , then the widget might be undergoing destruction or even be completely deleted, so the connector should not attempt to access the widget. This latter case can occur when the window holding the widget is closed and the widget is destroyed, but the connector has not yet been told to delete itself. This occurs when a focus out event is sent as part of the widget destruction and this gets processed before the signal that leads to the connector being deleted. |
This function is called under certain circumstances where the connector needs to ensure that any unsaved changes are committed to the data attached to this connector. Text entry widgets are one example where a form of delayed change commit is often used to prevent a data update from being triggered every time the user presses a key. In such cases, the connector will only update the data when some other event occurs, such as when the user presses Enter or certain focus-related events are raised. Note that the widget losing focus needs to be handled specially (see details below).
This function will only ever be called when there are uncommitted changes, ie when haveUncommittedChanges() returns true
. If the subclass never calls madeUncommittedChange(), then flushChanges() will never be called and the subclass would not need to override flushChanges(). Conversely, if the subclass does call madeUncommittedChange(), then it must override flushChanges() to handle the situation where widgetWillRemainAlive is false
.
The cases where this function will be called include things like just before an input is serialized (if the widget is connected to an input) or just before the workspace in which the underlying data resides starts execution. In these two cases, safeToAccessWidget will be true
. The function can also be called when the widget loses focus or when the keyboard focus moves from one window to another. For these focus-related scenarios, safeToAccessWidget will be false
because the widget could be in a state of partial destruction.
Even if safeToAccessWidget is true
, it is not safe to assume that the underlying data can be safely accessed directly. If subclasses override this function, the normal steps taken when safeToAccessWidget is true
are to update any internal data within the connector and/or the widget itself, then call requestUpdateData() to ensure the data is updated in a safe manner.
When safeToAccessWidget is false
, subclasses that override this function will generally call commitData() instead of requestUpdateData(). This is because commitData() makes a copy of the data to be committed and it does not rely on the widget being in existence, whereas requestUpdateData() generally does rely on the widget still being available.
A typical reimplementation will look something like the following (this example is from the connector between QString data and a QTextEdit widget):
The default implementation calls requestUpdateData() if safeToAccessWidget is true
and it does nothing if safeToAccessWidget is false
.
NamePath & getNamePath | ( | ) |
QUuid getUuid | ( | ) | const |
QWidget & getWidget | ( | ) |
|
slot |
|
protected |
|
protectedslot |
Subclasses must call this function if they implement delayed commits. It should be called whenever a change is made in the widget which should ultimately be reflected in the underlying data, but for which the data does not need to be updated immediately. Text entry widgets are a classic example of this. They would call this function whenever any change is made to the text, but they might only request that the underlying data be updated when the user presses Enter or when the base class determines that data should be committed (eg the widget loses focus, serialization is about to occur on the data, etc.).
|
slot |
Schedules an update request for the widget. The next time the execution thread responsible for the connector's associated input/output is paused, the connector will call updateWidget() in the main GUI thread. Clients may call this function as and when necessary. Multiple calls will be compressed into a single call so that only one update is triggered for a given execution thread pause.
|
slot |
Schedules an update request for the widget. The next time the execution thread responsible for the connector's associated input/output is paused, the connector will call updateWidget() in the main GUI thread. Clients may call this function as and when necessary. Multiple calls will be compressed into a single call so that only one update is triggered for a given execution thread pause.
bool setAdaptorFactory | ( | const DataExecution::TypeAdaptorFactory * | adaptorFactory | ) |
adaptorFactory | An AdaptorFactory that could adapt the underlying data object to be used in the widget. Or nullptr to not doing any adaption. |
|
protected |
|
virtual |
b | Toggles widget to read only model. |
The Workspace editor calls this function to toggle read only behavior where modification of underlying data has no meaningful effect. Consider the scenario where a widget is attached to an Input which is connected to some other Output in a workflow. Any changes through this widget are lost when the Input is brought up to date because the data type is overwritten by data from the connected output.
The default implementation for this virtual method simply disables the entire widget. This method should be overridden for widgets that require some level of interaction in read only mode.
Reimplemented in ConversionSpinBoxConnector, ChartWidgetConnector, ImageWidgetConnector, PlotWidgetConnector, DataCollectionWidgetConnector, DataSeriesWidgetConnector, ImageTileViewConnector, ScientificDoubleSpinBoxConnector, SqlDatabaseWidgetConnector, SqlDataTableWidgetConnector, SqlResultSetTableWidgetConnector, Matrix3x3WidgetConnector, MeshModelInterfaceComboBoxConnector, MeshModelInterfaceInspectorWidgetConnector, MeshModelInterfaceSummaryWidgetConnector, MeshModelInterfaceWidgetConnector, MeshModelWidgetConnector, MeshReadersComboBoxConnector, QVectorVector3dWidgetConnector, TransformByComponentsConnector, TransformMatrixConnector, Vector3dGroupDegreesWidgetConnector, Vector3dGroupWidgetConnector, SchedulerServerSelectionWidgetConnector, WSGLGridWidgetConnector, WSGLWidgetConnector, SceneInteractionWidgetConnector, ScreenNumberWidgetConnector, ScreenSerialNumberWidgetConnector, MergeProgressWidgetConnector, WorkflowDifferencesWidgetConnector, WorkflowValidatorWidgetConnector, DataTableWidgetConnector, DateTimeWidgetConnector, DoubleLineEditConnector, DoubleSpinBoxConnector, FileNameWidgetConnector, FloatSpinBoxConnector, IntegerLineEditConnector, IntegerSpinBoxConnector, JsonJSEditConnector, MultipleFileNamesWidgetConnector, ObjectArrayWidgetConnector, ObjectDictionaryTableViewWidgetConnector, ObjectDictionaryWidgetConnector, ObjectGroupWidgetConnector, PasswordWidgetConnector, QByteArrayLabelConnector, QPointFLineEditConnector, QVariantWidgetConnector, RangedSpinBoxConnector, ShowWidgetButtonConnector, StringComboBoxConnector, StringJSEditConnector, StringLineEditConnector, StringListLineEditConnector, StringListWidgetConnector, StringSelectionWidgetConnector, StringTextEditConnector, TimeStampFormatWidgetConnector, VariantLabelConnector, and VariantLineEditConnector.
|
slot |
This function is somewhat similar to requestUpdateWidget() in that it updates the widget to reflect the value of the underlying data it is attached to. The difference here is that synchronizeWithData() will try to bring the underlying input up to date if there is one to update and if it is safe to do so as part of the call. If there is no running updater but the input cannot be brought up to date, this function does nothing and simply lets the usual update mechanisms take their course to eventually update the widget when it can be done.