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  int
83  {
84  return static_cast<int>(std::round(1000 / _frequencySpinBox->value()));
85  }
86 
87  void
89  {
90  /* A QTimer can only be started and stopped within its own thread (the thread for which
91  * it has the greatest affinity). Since this method can be called from any thread, we
92  * need to take a detour through these signals, which can be emitted from any thread and
93  * will always be caught in this object's (and thus the timer's) native thread.
94  */
95  if (_autoCheckBox->isChecked())
96  {
97  emit startTimerSignal();
98  }
99  else
100  {
101  emit stopTimerSignal();
102  }
103  }
104 
105  void
107  {
108  // See `startTimerIfEnabled` for the signal reasoning.
109  emit stopTimerSignal();
110  }
111 
112  void
113  PeriodicUpdateWidget::_updateTimerFrequency()
114  {
115  _timer->setInterval(getUpdateIntervalMs());
116  }
117 
118  void
119  PeriodicUpdateWidget::_toggleAutoUpdates(bool enabled)
120  {
121  // This method is already a slot, so it doesn't need to use the timer signals.
122  _frequencySpinBox->setEnabled(enabled);
123  if (enabled)
124  {
125  _timer->start();
126  }
127  else
128  {
129  _timer->stop();
130  }
131  }
132 
133  QCheckBox*
135  {
136  return _autoCheckBox;
137  }
138 
139  QDoubleSpinBox*
141  {
142  return _frequencySpinBox;
143  }
144 
145  QTimer*
147  {
148  return _timer;
149  }
150 
151 } // 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:134
armarx::armem::gui::PeriodicUpdateWidget::update
void update()
armarx::armem::gui::PeriodicUpdateWidget::timer
QTimer * timer()
Definition: PeriodicUpdateWidget.cpp:146
enabled
std::atomic< bool > * enabled
Definition: RemoteGuiWidgetController.cpp:75
PeriodicUpdateWidget.h
armarx::armem::gui::PeriodicUpdateWidget::frequencySpinBox
QDoubleSpinBox * frequencySpinBox()
Definition: PeriodicUpdateWidget.cpp:140
armarx::armem::gui::PeriodicUpdateWidget::getUpdateIntervalMs
int getUpdateIntervalMs() const
Definition: PeriodicUpdateWidget.cpp:82
armarx::armem::gui
Definition: ActionsMenuBuilder.cpp:6
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:106
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:88