DynExp
Highly flexible laboratory automation for dynamically changing experiments.
SpectrumViewer.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "moc_SpectrumViewer.cpp"
5 #include "SpectrumViewer.h"
6 
8 {
10  : QModuleWidget(Owner, parent),
11  DataSeries(nullptr), DataChart(nullptr), XAxis(nullptr), YAxis(nullptr)
12  {
13  ui.setupUi(this);
14 
15  // For shortcuts
16  this->addAction(ui.action_Run);
17  this->addAction(ui.action_Stop);
18 
19  DataChart = new QChart();
20  ui.Spectrum->setChart(DataChart); // Takes ownership of DataChart.
21  ui.Spectrum->setRenderHint(QPainter::Antialiasing);
23  DataChart->legend()->setVisible(false);
24  }
25 
27  {
28  ui.SBExposureTime->setRange(ModuleData->MinExposureTime.count(), ModuleData->MaxExposureTime.count());
29  ui.SBExposureTime->setSuffix(" " + QString::fromStdString(Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>()));
30  ui.SBLowerFrequency->setRange(ModuleData->MinFrequency, ModuleData->MaxFrequency);
31  ui.SBLowerFrequency->setSuffix(" " + QString(DynExpInstr::SpectrometerData::FrequencyUnitTypeToStr(ModuleData->FrequencyUnit)));
32  ui.SBUpperFrequency->setRange(ModuleData->MinFrequency, ModuleData->MaxFrequency);
33  ui.SBUpperFrequency->setSuffix(" " + QString(DynExpInstr::SpectrometerData::FrequencyUnitTypeToStr(ModuleData->FrequencyUnit)));
34 
35  if (XAxis)
36  {
37  DataChart->removeAxis(XAxis);
38  delete XAxis;
39  }
40  if (YAxis)
41  {
42  DataChart->removeAxis(YAxis);
43  delete YAxis;
44  }
45 
46  XAxis = new QValueAxis(this);
47  YAxis = new QValueAxis(this);
48  XAxis->setTitleText(QString("Frequency in ") + DynExpInstr::SpectrometerData::FrequencyUnitTypeToStr(ModuleData->FrequencyUnit));
49  XAxis->setLabelFormat("%d");
50  YAxis->setTitleText(QString("Intensity in ") + DynExpInstr::SpectrometerData::IntensityUnitTypeToStr(ModuleData->IntensityUnit));
51  YAxis->setLabelFormat("%d");
52 
53  // Chart takes ownership of axes.
54  DataChart->addAxis(XAxis, Qt::AlignBottom);
55  DataChart->addAxis(YAxis, Qt::AlignLeft);
56  }
57 
59  {
60  ui.action_Save_CSV->setEnabled(ModuleData->CapturingState != DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
61  ui.action_Run->setEnabled(ModuleData->CapturingState != DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
62  ui.action_Stop->setEnabled(ModuleData->CapturingState == DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
63  ui.SBExposureTime->setEnabled(ModuleData->CapturingState != DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
64  ui.SBLowerFrequency->setEnabled(ModuleData->CapturingState != DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
65  ui.SBUpperFrequency->setEnabled(ModuleData->CapturingState != DynExpInstr::SpectrometerData::CapturingStateType::Capturing);
66 
67  {
68  const QSignalBlocker Blocker(ui.action_SilentMode);
69  ui.action_SilentMode->setChecked(ModuleData->SilentModeEnabled);
70  } // Blocker destroyed here.
71 
72  if (!ui.SBExposureTime->hasFocus())
73  {
74  const QSignalBlocker Blocker(ui.SBExposureTime);
75  ui.SBExposureTime->setValue(ModuleData->CurrentExposureTime.count());
76  }
77 
78  if (!ui.SBLowerFrequency->hasFocus())
79  {
80  const QSignalBlocker Blocker(ui.SBLowerFrequency);
81  ui.SBLowerFrequency->setValue(ModuleData->CurrentLowerFrequency);
82  }
83 
84  if (!ui.SBUpperFrequency->hasFocus())
85  {
86  const QSignalBlocker Blocker(ui.SBUpperFrequency);
87  ui.SBUpperFrequency->setValue(ModuleData->CurrentUpperFrequency);
88  }
89 
90  switch (ModuleData->CapturingState)
91  {
93  ui.LState->setText(" Acquiring spectrum...");
94  ui.LState->setStyleSheet(DynExpUI::StatusBarBusyStyleSheet);
95  break;
97  ui.LState->setText(" The spectrometer is in a warning state.");
98  ui.LState->setStyleSheet(DynExpUI::StatusBarWarningStyleSheet);
99  break;
101  ui.LState->setText(" The spectrometer is in an error state.");
102  ui.LState->setStyleSheet(DynExpUI::StatusBarErrorStyleSheet);
103  break;
104  default:
105  ui.LState->setText(" Ready");
106  ui.LState->setStyleSheet("");
107  }
108 
109  ui.PBProgress->setVisible(ModuleData->CapturingState == DynExpInstr::SpectrometerData::CapturingStateType::Capturing
110  && ModuleData->CapturingProgress > 0);
111  ui.PBProgress->setValue(ModuleData->CapturingProgress > 0 ? Util::NumToT<int>(ModuleData->CapturingProgress) : 0);
112  }
113 
115  {
116  if (SampleData.Points.empty() || IsSavingData)
117  return;
118 
119  CurrentSpectrum = std::move(SampleData);
120  CurrentExposureTime = ExposureTime;
121 
122  // DataSeries->replace() does not work...
123  DataChart->removeAllSeries();
124 
125  DataSeries = new QLineSeries(this);
127  DataSeries->setPointsVisible(false);
128 
129  DataChart->axes()[0]->setRange(CurrentSpectrum.MinValues.x(), CurrentSpectrum.MaxValues.x());
131  {
132  auto Factor = std::abs(CurrentSpectrum.MinValues.y()) * .01;
133  if (Factor == 0)
134  Factor = 2;
135 
136  DataChart->axes()[1]->setRange(CurrentSpectrum.MinValues.y() - Factor, CurrentSpectrum.MaxValues.y() + Factor);
137  }
138  else
139  DataChart->axes()[1]->setRange(CurrentSpectrum.MinValues.y(), CurrentSpectrum.MaxValues.y());
140 
141  DataChart->addSeries(DataSeries);
142  DataSeries->attachAxis(DataChart->axes()[0]);
143  DataSeries->attachAxis(DataChart->axes()[1]);
144  }
145 
147  {
148  // As soon as FinishedSavingDataGuard is destroyed, IsSavingData is set back to false.
150  IsSavingData = true;
151 
152  auto Filename = Util::PromptSaveFilePathModule(this, "Save data", ".csv", " Comma-separated values file (*.csv)");
153  if (Filename.isEmpty())
154  return;
155 
157  QMessageBox::warning(this, "DynExp - Error", "Error writing data to file.");
158  }
159 
161  {
162  Points.clear();
163 
164  MinValues = {};
165  MaxValues = {};
166 
169  }
170 
172  {
173  std::stringstream CSVData;
174  CSVData << std::setprecision(6);
175  CSVData << "ExposureTime = " << ExposureTime.count() << " " << Util::ToUnitStr<DynExpInstr::SpectrometerData::TimeType>() << "\n";
176  CSVData << "HEADER_END\n";
177 
178  CSVData << "f[" << DynExpInstr::SpectrometerData::FrequencyUnitTypeToStr(FrequencyUnit)
179  << "];I[" << DynExpInstr::SpectrometerData::IntensityUnitTypeToStr(IntensityUnit) << "]\n";
180  for (const auto& Sample : Points)
181  CSVData << Sample.x() << ";" << Sample.y() << "\n";
182 
183  return CSVData.str();
184  }
185 
187  {
188  Init();
189  }
190 
192  {
195  MinFrequency = 0.0;
196  MaxFrequency = 0.0;
197  MinExposureTime = DynExpInstr::SpectrometerData::TimeType();
198  MaxExposureTime = DynExpInstr::SpectrometerData::TimeType();
200  AcquisitionExposureTime = DynExpInstr::SpectrometerData::TimeType();
201  CurrentLowerFrequency = 0.0;
202  CurrentUpperFrequency = 0.0;
203  SilentModeEnabled = false;
205  CapturingProgress = 0.0;
206  AutoSaveFilename.clear();
208  SpectrumRecordingPaused = false;
209 
210  UIInitialized = false;
211  }
212 
214  {
215  try
216  {
217  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance.ModuleDataGetter());
218  auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
219 
220  ModuleData->CurrentExposureTime = InstrData->GetCurrentExposureTime();
221  ModuleData->CurrentLowerFrequency = InstrData->GetCurrentLowerFrequency();
222  ModuleData->CurrentUpperFrequency = InstrData->GetCurrentUpperFrequency();
223  ModuleData->SilentModeEnabled = InstrData->GetSilentModeEnabled();
224  ModuleData->CapturingState = InstrData->GetCapturingState();
225  ModuleData->CapturingProgress = InstrData->GetCapturingProgress();
226 
227  if (InstrData->HasSpectrum() && !ModuleData->SpectrumRecordingPaused)
228  {
229  ModuleData->CurrentSpectrum = ProcessSpectrum(InstrData->GetSpectrum(), ModuleData);
230 
231  if (!ModuleData->CurrentSpectrum.Points.empty())
232  {
233  if (ModuleData->GetCommunicator().valid() && !ModuleData->AutoSaveFilename.empty())
234  ModuleData->GetCommunicator()->PostEvent(*this, SpectrumFinishedRecordingEvent{});
235 
236  ModuleData->AutoSaveFilename.clear();
237  }
238  }
239 
240  NumFailedUpdateAttempts = 0;
241  } // ModuleData and instruments' data unlocked here.
242  catch (const Util::TimeoutException& e)
243  {
244  if (NumFailedUpdateAttempts++ >= 3)
245  Instance.GetOwner().SetWarning(e);
246  }
247 
249  }
250 
252  {
253  NumFailedUpdateAttempts = 0;
254  }
255 
256  std::unique_ptr<DynExp::QModuleWidget> SpectrumViewer::MakeUIWidget()
257  {
258  auto Widget = std::make_unique<SpectrumViewerWidget>(*this);
259 
260  Connect(Widget->GetUI().action_Run, &QAction::triggered, this, &SpectrumViewer::OnRunClicked);
261  Connect(Widget->GetUI().action_Stop, &QAction::triggered, this, &SpectrumViewer::OnStopClicked);
262  Connect(Widget->GetUI().action_SilentMode, &QAction::toggled, this, &SpectrumViewer::OnSilentModeToggled);
263  Connect(Widget->GetUI().SBExposureTime, QOverload<int>::of(&QSpinBox::valueChanged), this, &SpectrumViewer::OnExposureTimeChanged);
264  Connect(Widget->GetUI().SBLowerFrequency, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &SpectrumViewer::OnLowerLimitChanged);
265  Connect(Widget->GetUI().SBUpperFrequency, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &SpectrumViewer::OnUpperLimitChanged);
266 
267  return Widget;
268  }
269 
270  void SpectrumViewer::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
271  {
272  auto Widget = GetWidget<SpectrumViewerWidget>();
273  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(ModuleDataGetter());
274 
275  if (!ModuleData->IsUIInitialized())
276  {
277  Widget->InitializeUI(ModuleData);
278  ModuleData->SetUIInitialized();
279  }
280 
281  Widget->UpdateUI(ModuleData);
282 
283  if (!ModuleData->CurrentSpectrum.Points.empty())
284  Widget->SetData(std::move(ModuleData->CurrentSpectrum), ModuleData->AcquisitionExposureTime);
285  }
286 
289  {
290  SpectrumViewerWidget::SampleDataType TransformedSpectrum;
291  TransformedSpectrum.FrequencyUnit = Spectrum.GetFrequencyUnit();
292  TransformedSpectrum.IntensityUnit = Spectrum.GetIntensityUnit();
293 
294  if (!Spectrum.HasSpectrum())
295  return TransformedSpectrum;
296 
297  double YMin(std::numeric_limits<double>::max()), YMax(std::numeric_limits<double>::lowest());
298  for (const auto& Sample : Spectrum.GetSpectrum())
299  {
300  TransformedSpectrum.Points.append({ Sample.first, Sample.second });
301 
302  YMin = std::min(YMin, Sample.second);
303  YMax = std::max(YMax, Sample.second);
304  }
305 
306  TransformedSpectrum.MinValues = { Spectrum.GetSpectrum().begin()->first, YMin};
307  TransformedSpectrum.MaxValues = { Spectrum.GetSpectrum().rbegin()->first, YMax};
308 
309  if (!ModuleData->AutoSaveFilename.empty())
310  SaveSpectrum(TransformedSpectrum, ModuleData);
311 
312  return TransformedSpectrum;
313  }
314 
317  {
318  if (!Util::SaveToFile(QString::fromStdString(ModuleData->AutoSaveFilename), Spectrum.ToStr(ModuleData->CurrentExposureTime)))
319  Util::EventLogger().Log("Saving spectrum as \"" + ModuleData->AutoSaveFilename + "\" to file failed.", Util::ErrorType::Error);
320  else
321  Util::EventLogger().Log("Saved spectrum as \"" + ModuleData->AutoSaveFilename + "\" to file.");
322  }
323 
325  {
330 
331  auto ModuleParams = DynExp::dynamic_Params_cast<SpectrumViewer>(Instance->ParamsGetter());
332  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
333 
334  Instance->LockObject(ModuleParams->Spectrometer, ModuleData->GetSpectrometer());
335  if (ModuleParams->Communicator.ContainsID())
336  Instance->LockObject(ModuleParams->Communicator, ModuleData->GetCommunicator());
337 
338  ModuleData->FrequencyUnit = ModuleData->GetSpectrometer()->GetFrequencyUnit();
339  ModuleData->IntensityUnit = ModuleData->GetSpectrometer()->GetIntensityUnit();
340  ModuleData->MinFrequency = ModuleData->GetSpectrometer()->GetMinFrequency();
341  ModuleData->MaxFrequency = ModuleData->GetSpectrometer()->GetMaxFrequency();
342 
343  auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
344  ModuleData->MinExposureTime = InstrData->GetMinExposureTime();
345  ModuleData->MaxExposureTime = InstrData->GetMaxExposureTime();
346  }
347 
349  {
350  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
351 
352  Instance->UnlockObject(ModuleData->GetSpectrometer());
353  Instance->UnlockObject(ModuleData->GetCommunicator());
354 
359  }
360 
362  {
363  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
364 
365  ModuleData->SpectrumRecordingPaused = false;
366  ModuleData->AcquisitionExposureTime = ModuleData->CurrentExposureTime;
367  ModuleData->GetSpectrometer()->Record();
368  }
369 
371  {
372  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
373 
374  ModuleData->SpectrumRecordingPaused = false;
375  ModuleData->AutoSaveFilename.clear();
376  ModuleData->GetSpectrometer()->Abort();
377  }
378 
380  {
381  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
382 
383  ModuleData->GetSpectrometer()->SetSilentMode(Checked);
384  }
385 
387  {
388  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
389 
390  ModuleData->GetSpectrometer()->SetExposureTime(DynExpInstr::SpectrometerData::TimeType(Value));
391  }
392 
394  {
395  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
396  auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
397 
398  if (Value < InstrData->GetCurrentUpperFrequency())
399  ModuleData->GetSpectrometer()->SetFrequencyRange(Value, InstrData->GetCurrentUpperFrequency());
400  }
401 
403  {
404  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
405  auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::Spectrometer>(ModuleData->GetSpectrometer()->GetInstrumentData());
406 
407  if (Value > InstrData->GetCurrentLowerFrequency())
408  ModuleData->GetSpectrometer()->SetFrequencyRange(InstrData->GetCurrentLowerFrequency(), Value);
409  }
410 
411  void SpectrumViewer::OnRecordAndSaveSpectrum(DynExp::ModuleInstance* Instance, std::string SaveDataFilename) const
412  {
413  {
414  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
415 
416  if (ModuleData->CapturingState == DynExpInstr::SpectrometerData::CapturingStateType::Capturing)
417  return;
418 
419  ModuleData->SpectrumRecordingPaused = false;
420  ModuleData->AutoSaveFilename = SaveDataFilename;
421  } // ModuleData unlocked here.
422 
423  OnRunClicked(Instance, false);
424  }
425 
427  {
428  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
429  ModuleData->SpectrumRecordingPaused = true;
430  }
431 
433  {
434  auto ModuleData = DynExp::dynamic_ModuleData_cast<SpectrumViewer>(Instance->ModuleDataGetter());
435  ModuleData->SpectrumRecordingPaused = false;
436  }
437 }
Implementation of a module to plot the spectrum stored in a spectrometer instrument.
Type describing a spectrum as acquired by the Spectrometer instrument.
Definition: Spectrometer.h:121
@ Warning
The spectrometer is in a warning state, but still ready to acquire a spectrum.
@ Capturing
The spectrometer is currently acquiring a spectrum.
@ Error
The spectrometer is in an error state.
@ Ready
The spectrometer is ready to acquire a spectrum.
static const char * IntensityUnitTypeToStr(const IntensityUnitType &Unit)
Returns a descriptive string of a respective intensity unit to be e.g. used in plots.
std::chrono::milliseconds TimeType
Time type describing the spectrometer's times like its exposure time.
Definition: Spectrometer.h:71
static const char * FrequencyUnitTypeToStr(const FrequencyUnitType &Unit)
Returns a descriptive string of a respective frequency unit to be e.g. used in plots.
Definition: Spectrometer.cpp:8
@ Counts
Number of counts (arbitrary unit)
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
SpectrumViewerWidget(SpectrumViewer &Owner, QModuleWidget *parent=nullptr)
void UpdateUI(Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
void InitializeUI(Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
DynExpInstr::SpectrometerData::TimeType CurrentExposureTime
void SetData(SampleDataType &&SampleData, DynExpInstr::SpectrometerData::TimeType ExposureTime)
void OnRunClicked(DynExp::ModuleInstance *Instance, bool) const
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
void OnUpperLimitChanged(DynExp::ModuleInstance *Instance, double Value) const
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(DynExp::ModuleInstance &Instance) override final
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
void OnStopClicked(DynExp::ModuleInstance *Instance, bool) const
void OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
void OnPauseSpectrumRecording(DynExp::ModuleInstance *Instance) const
void ResetImpl(dispatch_tag< QModuleBase >) override final
void OnLowerLimitChanged(DynExp::ModuleInstance *Instance, double Value) const
std::unique_ptr< DynExp::QModuleWidget > MakeUIWidget() override final
Used by InitUI() as a factory function for the module's user interface widget. Create the widget here...
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void SaveSpectrum(const SpectrumViewerWidget::SampleDataType &Spectrum, Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
SpectrumViewerWidget::SampleDataType ProcessSpectrum(DynExpInstr::SpectrometerData::SpectrumType &&Spectrum, Util::SynchronizedPointer< SpectrumViewerData > &ModuleData)
void OnSilentModeToggled(DynExp::ModuleInstance *Instance, bool Checked) const
void OnResumeSpectrumRecording(DynExp::ModuleInstance *Instance) const
void OnRecordAndSaveSpectrum(DynExp::ModuleInstance *Instance, std::string SaveDataFilename) const
void OnExposureTimeChanged(DynExp::ModuleInstance *Instance, int Value) const
static void Register(const ModuleBase &Listener, CallableT EventFunc)
Registers/Subscribes module Listener to the event with the event function EventFunc....
Definition: Module.h:1028
static void Deregister(const ModuleBase &Listener)
Deregisters/unsubscribes module Listener from the event. Indirectly calls ModuleBase::RemoveRegistere...
Definition: Module.h:1034
Refer to ParamsBase::dispatch_tag.
Definition: Module.h:189
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition: Module.h:793
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition: Module.h:825
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition: Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition: Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT >> &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition: Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition: Object.h:3524
Logs events like errors and writes them immediately to a HTML file in a human-readable format....
Definition: Util.h:1061
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
Definition: Util.cpp:309
Holds a CallableMemberWrapper and invokes its callable when being destroyed.
Definition: Util.h:494
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition: Util.h:170
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
constexpr auto DefaultQChartTheme
constexpr auto StatusBarWarningStyleSheet
constexpr auto StatusBarErrorStyleSheet
constexpr auto StatusBarBusyStyleSheet
DynExpErrorCodes
DynExp's error codes
Definition: Exception.h:22
bool SaveToFile(const QString &Filename, std::string_view Text)
Saves a std::string_view to a file (using QFile). Creates a new file or truncates an existing file's ...
Definition: QtUtil.cpp:236
QString PromptSaveFilePathModule(DynExp::QModuleWidget *Parent, const QString &Title, const QString &DefaultSuffix, const QString &NameFilter)
Works as PromptOpenFilePath() but asks the user to select a single file which does not need to exist....
Definition: QtUtil.cpp:143
Accumulates include statements to provide a precompiled header.
DynExpInstr::SpectrometerData::IntensityUnitType IntensityUnit
DynExpInstr::SpectrometerData::FrequencyUnitType FrequencyUnit
std::string ToStr(DynExpInstr::SpectrometerData::TimeType ExposureTime) const