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