PeriodicUpdateWidget.cpp
Go to the documentation of this file.
2
3#include <cmath>
4
5#include <QCheckBox>
6#include <QDoubleSpinBox>
7#include <QHBoxLayout>
8#include <QPushButton>
9#include <QTimer>
10
11namespace armarx
12{
13 PeriodicUpdateWidget::PeriodicUpdateWidget(double frequency, double maxFrequency)
14 {
15 setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
16
17 QLayout* vlayout = new QVBoxLayout();
18 QLayout* hlayout = new QHBoxLayout();
19 this->setLayout(vlayout);
20
21 const int margin = 0;
22 hlayout->setContentsMargins(margin, margin, margin, margin);
23
24 _updateButton = new QPushButton("Update", this);
25 _autoCheckBox = new QCheckBox("Auto Update", this);
26 _frequencySpinBox = new QDoubleSpinBox(this);
27 _frequencySpinBox->setValue(frequency);
28 _frequencySpinBox->setMinimum(0);
29 _frequencySpinBox->setMaximum(maxFrequency);
30 _frequencySpinBox->setSingleStep(0.5);
31 _frequencySpinBox->setSuffix(" Hz");
32
33 hlayout->addWidget(_updateButton);
34 hlayout->addWidget(_autoCheckBox);
35 hlayout->addWidget(_frequencySpinBox);
36
37 vlayout->addItem(hlayout);
38
39
40 _timer = new QTimer(this);
41 _updateTimerFrequency();
42 _frequencySpinBox->setEnabled(_autoCheckBox->isChecked());
43
44
45 // Private connections.
46 connect(_autoCheckBox, &QCheckBox::toggled, this, &This::_toggleAutoUpdates);
47 connect(_frequencySpinBox,
48 &QDoubleSpinBox::editingFinished,
49 this,
50 &This::_updateTimerFrequency);
51
52 // Public connections.
53 connect(_updateButton, &QPushButton::pressed, this, &This::updateSingle);
54 connect(_timer, &QTimer::timeout, this, &This::updatePeriodic);
55
56 connect(this, &This::updateSingle, this, &This::update);
57 connect(this, &This::updatePeriodic, this, &This::update);
58
59 // See `startTimerIfEnabled` for the signal reasoning.
60 // qOverload is required because `QTimer::start()` is overloaded.
61 connect(this, &This::startTimerSignal, _timer, qOverload<>(&QTimer::start));
62 connect(this, &This::stopTimerSignal, _timer, &QTimer::stop);
63 }
64
65 QPushButton*
67 {
68 return _updateButton;
69 }
70
71 int
73 {
74 return static_cast<int>(std::round(1000 / _frequencySpinBox->value()));
75 }
76
77 void
79 {
80 /* A QTimer can only be started and stopped within its own thread (the thread for which
81 * it has the greatest affinity). Since this method can be called from any thread, we
82 * need to take a detour through these signals, which can be emitted from any thread and
83 * will always be caught in this object's (and thus the timer's) native thread.
84 */
85 if (_autoCheckBox->isChecked())
86 {
87 emit startTimerSignal();
88 }
89 else
90 {
91 emit stopTimerSignal();
92 }
93 }
94
95 void
97 {
98 // See `startTimerIfEnabled` for the signal reasoning.
99 emit stopTimerSignal();
100 }
101
102 void
103 PeriodicUpdateWidget::_updateTimerFrequency()
104 {
105 _timer->setInterval(getUpdateIntervalMs());
106 }
107
108 void
109 PeriodicUpdateWidget::_toggleAutoUpdates(bool enabled)
110 {
111 // This method is already a slot, so it doesn't need to use the timer signals.
112 _frequencySpinBox->setEnabled(enabled);
113 if (enabled)
114 {
115 _timer->start();
116 }
117 else
118 {
119 _timer->stop();
120 }
121 }
122
123 QCheckBox*
125 {
126 return _autoCheckBox;
127 }
128
129 QDoubleSpinBox*
131 {
132 return _frequencySpinBox;
133 }
134
135 QTimer*
137 {
138 return _timer;
139 }
140
141} // namespace armarx
PeriodicUpdateWidget(double frequency=2.0, double maxFrequency=60)
This file offers overloads of toIce() and fromIce() functions for STL container types.