Skip to content
Snippets Groups Projects

Add PeriodicUpdateWidget

Merged Peter Albrecht requested to merge feature/PeriodicUpdateWidget into master
3 files
+ 209
0
Compare changes
  • Side-by-side
  • Inline
Files
3
#include "PeriodicUpdateWidget.h"
#include <cmath>
#include <QCheckBox>
#include <QDoubleSpinBox>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTimer>
namespace armarx::skills::gui
{
PeriodicUpdateWidget::PeriodicUpdateWidget(double frequency, double maxFrequency)
{
setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
QLayout* vlayout = new QVBoxLayout();
QLayout* hlayout = new QHBoxLayout();
this->setLayout(vlayout);
const int margin = 0;
hlayout->setContentsMargins(margin, margin, margin, margin);
_updateButton = new QPushButton("Update", this);
_autoCheckBox = new QCheckBox("Auto Update", this);
_frequencySpinBox = new QDoubleSpinBox(this);
_frequencySpinBox->setValue(frequency);
_frequencySpinBox->setMinimum(0);
_frequencySpinBox->setMaximum(maxFrequency);
_frequencySpinBox->setSingleStep(0.5);
_frequencySpinBox->setSuffix(" Hz");
hlayout->addWidget(_updateButton);
hlayout->addWidget(_autoCheckBox);
hlayout->addWidget(_frequencySpinBox);
vlayout->addItem(hlayout);
_timer = new QTimer(this);
_updateTimerFrequency();
_frequencySpinBox->setEnabled(_autoCheckBox->isChecked());
// Private connections.
connect(_autoCheckBox, &QCheckBox::toggled, this, &This::_toggleAutoUpdates);
connect(_frequencySpinBox,
&QDoubleSpinBox::editingFinished,
this,
&This::_updateTimerFrequency);
// Public connections.
connect(_updateButton, &QPushButton::pressed, this, &This::updateSingle);
connect(_timer, &QTimer::timeout, this, &This::updatePeriodic);
connect(this, &This::updateSingle, this, &This::update);
connect(this, &This::updatePeriodic, this, &This::update);
// See `startTimerIfEnabled` for the signal reasoning.
// qOverload is required because `QTimer::start()` is overloaded.
connect(this, &This::startTimerSignal, _timer, qOverload<>(&QTimer::start));
connect(this, &This::stopTimerSignal, _timer, &QTimer::stop);
}
QPushButton*
PeriodicUpdateWidget::updateButton()
{
return _updateButton;
}
int
PeriodicUpdateWidget::getUpdateIntervalMs() const
{
return static_cast<int>(std::round(1000 / _frequencySpinBox->value()));
}
void
PeriodicUpdateWidget::startTimerIfEnabled()
{
/* A QTimer can only be started and stopped within its own thread (the thread for which
* it has the greatest affinity). Since this method can be called from any thread, we
* need to take a detour through these signals, which can be emitted from any thread and
* will always be caught in this object's (and thus the timer's) native thread.
*/
if (_autoCheckBox->isChecked())
{
emit startTimerSignal();
}
else
{
emit stopTimerSignal();
}
}
void
PeriodicUpdateWidget::stopTimer()
{
// See `startTimerIfEnabled` for the signal reasoning.
emit stopTimerSignal();
}
void
PeriodicUpdateWidget::_updateTimerFrequency()
{
_timer->setInterval(getUpdateIntervalMs());
}
void
PeriodicUpdateWidget::_toggleAutoUpdates(bool enabled)
{
// This method is already a slot, so it doesn't need to use the timer signals.
_frequencySpinBox->setEnabled(enabled);
if (enabled)
{
_timer->start();
}
else
{
_timer->stop();
}
}
QCheckBox*
PeriodicUpdateWidget::autoCheckBox()
{
return _autoCheckBox;
}
QDoubleSpinBox*
PeriodicUpdateWidget::frequencySpinBox()
{
return _frequencySpinBox;
}
QTimer*
PeriodicUpdateWidget::timer()
{
return _timer;
}
} // namespace armarx
Loading