The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 4f72e6fd authored by Artur Grunau's avatar Artur Grunau
Browse files

Update property widgets in the GUI thread

AbstractPropertyWidget's onPropertyChanged slot is invoked from non-GUI
threads. Previously, it would call updateWidgetFromProperty directly,
which resulted in Qt widgets being accessed from non-GUI threads. This
in turn led to random crashes when properties were modified quickly and
repeatedly from the GUI.

Now we invoke updateWidgetFromProperty via a signal-slot connection with
an internal signal, s_propertyChanged. This makes Qt take care of
queueing slot accesses in the GUI thread for us.

Fixes #36
parent 8b316f0c
......@@ -58,6 +58,7 @@ namespace campvis {
}
_property->s_changed.connect(this, &AbstractPropertyWidget::onPropertyChanged);
connect(this, SIGNAL(s_propertyChanged(const AbstractProperty*)), this, SLOT(updateWidgetFromProperty()));
}
AbstractPropertyWidget::~AbstractPropertyWidget() {
......@@ -70,6 +71,6 @@ namespace campvis {
void AbstractPropertyWidget::onPropertyChanged(const AbstractProperty* property) {
if (_ignorePropertyUpdates == 0)
updateWidgetFromProperty();
emit s_propertyChanged(property);
}
}
......@@ -62,24 +62,34 @@ namespace campvis {
*/
virtual ~AbstractPropertyWidget();
public slots:
protected:
/**
* Adds a widget to the local Qt layout.
*/
void addWidget(QWidget* widget);
AbstractProperty* _property; ///< The property this widget handles
/// Semaphore acts as flag whether the widget shall ignore incoming signals from properties being updated.
tbb::atomic<int> _ignorePropertyUpdates;
protected slots:
/**
* Gets called when the property has changed, so that widget can update its state.
*/
virtual void updateWidgetFromProperty() = 0;
AbstractProperty* _property; ///< The property this widget handles
/// Semaphore acts as flag whether the widget shall ignore incoming signals from properties being updated.
tbb::atomic<int> _ignorePropertyUpdates;
signals:
/**
* Internal signal used to update the property widget in a thread-safe way.
*
* This class' \ref onPropertyChanged() slot is invoked from non-GUI threads. As a result,
* \ref updateWidgetFromProperty() couldn't access any Qt widgets safely if it was called from there directly,
* because it would execute in a non-GUI thread. However, if we invoke \ref updateWidgetFromProperty() via
* a signal-slot connection with \ref s_propertyChanged(), Qt takes care of queueing slot accesses in the GUI
* thread for us.
*/
void s_propertyChanged(const AbstractProperty* property);
private:
/// Slot getting called when the property has changed, so that the widget can be updated.
......
......@@ -46,7 +46,6 @@ namespace campvis {
addWidget(_adjuster);
connect(_adjuster, SIGNAL(valueChanged(double)), this, SLOT(onAdjusterValueChanged(double)));
connect(this, SIGNAL(propertyValueChanged(double)), _adjuster, SLOT(setValue(double)));
property->s_minMaxChanged.connect(this, &FloatPropertyWidget::onPropertyMinMaxChanged);
}
......@@ -57,7 +56,7 @@ namespace campvis {
void FloatPropertyWidget::updateWidgetFromProperty() {
FloatProperty* prop = static_cast<FloatProperty*>(_property);
_adjuster->blockSignals(true);
emit propertyValueChanged(prop->getValue());
_adjuster->setValue(prop->getValue());
_adjuster->blockSignals(false);
}
......
......@@ -60,10 +60,6 @@ namespace campvis {
*/
virtual void updateWidgetFromProperty();
signals:
/// Signal emitted when the property's value changes
void propertyValueChanged(double value);
private slots:
/// Slot getting called when the adjuster's value changes
void onAdjusterValueChanged(double value);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment