6.1. Common to all kind of widgets

6.1.1. Widget Class Declaration

It is required that the widgets uses Signal, Slots and Properties as interface. GUIs should consider it their design the Qt event oriented paradigm. This paradigm is best suited when using Qt intended interfaces. This means:

Properties

Properties are members of a widget class definition that express a configuration. Later, when using the Qt Designer, properties are automatically displayed by the designer in the Property Editor tab.

Properties should use basic datatypes, such as int, unsigned int, float, bool, str.

A Property has normally a related signal that acts as a change notification, and a related slot that allows to set the property.

Signals

Signals are send by a widget when a property changes, or when an event of significance has happened, and the developer of the widget wants other GUI elements to react to this significant event.

Signals can be typeless, or can carry arguments. For example, when a QPushButton_ is `pushed`_, a typeless signals is send. When a QCheckBox_ has its stateChanged_, the signals carries the new state value.

Note

Signals require no implementation, only declaration.

Slots

Slots are normally a setter for a property, or allow to perform an action on the widget.

It is usefull to create Slots for Properties: then the developer may connect one signal that provides the value, and the slot that sets the value to the widget.

Tip

Declaring signals and slots is cheap and imposes no penalty in performance. Using connections in the same thread is a direct function call.

Warning

Connecting a signal to a slot in different threads is slow. Qt will by default create an event of with the arguments of the signal, and pass it to the appropiate Event Pump.

The definition of Properties in Python should be done as in this example:


The definition of Properties in Python should be done as in this example:

 1#include <QWidget>
 2
 3class AWidget : public QWidget
 4{
 5    Q_OBJECT
 6
 7    /**
 8     * @brief Altitude coordinate of the current position in radians.
 9     * @accessors getCurrentAlt(), setCurrentAlt(double)
10     */
11    Q_PROPERTY(double currentAlt MEMBER m_currentAlt READ getCurrentAlt WRITE setCurrentAlt NOTIFY currentAltChanged )
12
13public :
14    AWidget(QWidget* parent = Q_NULLPTR): QWidget(parent){
15    }
16    double getCurrentAlt(){
17        return this->m_currentAlt;
18    };
19
20public slots:
21    double setCurrentAlt(double newValue){
22        if( this->m_currentAlt != newValue ){
23            this->m_currentAlt = newValue;
24            emit currentAltChanged(this->m_currentAlt);
25        }
26    };
27
28signals:
29    void currentAltChanged(double newValue);
30
31private:
32    double m_currentAlt = 0.0;
33}

The comments over the Q_PROPERTY macro are doxygen compatible. Doxygen can be configured to process and understand Qt Properties, Signals and Slots.

Note that the signal has no implementation.

 1from PySide2.QtCore import QWidget, Signal, Property, Slot
 2
 3class AWidget(QWidget):
 4
 5    def __init__(self):
 6        self._current_alt = 0.0
 7
 8    def get_current_alt(self) -> double:
 9        """Gets the value of the current altitude
10        :returns: double with value of the current altitude in radians.
11        :rtype: double
12        """
13        return self._current_alt
14
15    @Slot(double)
16    def set_current_alt(self, new_value: double):
17        """Sets the current altitude to new_value.
18        :param[in]: new_value double with value of the current altitude in radians.
19        """
20        if( self._current_alt != new_value ):
21            self._current_alt = new_value
22            self.current_alt_changed.emit(self._current_alt)
23
24    ## Signal that indicates tha the current altitude has changed.
25    current_alt_changed = Signal(double)
26
27    ## Property that holds the current altitude to be rendered.
28    #  It uses radians as units
29    current_alt = Property(double, get_current_alt, set_current_alt, notify=current_alt_changed)

Error

Do not use QStringList as a bug in Qt 5.15 (https://jira.eso.org/browse/ETCS-1036, https://bugreports.qt.io/browse/PYSIDE-1942) does not make it usable under python. As a workaround until we port to Qt 6, please use QString with a separator.

6.1.2. WAF project/module for the Widget

After the declaration of the Widget, this files needs to part of WAF project. The preparation of a WAF project that can host Widget is discussed extensible in Widget Library Tutorial. Developers may also use the provided example code, or the template to create a new library for their own widgets.