From f8304501bad74c295a643b33e1e679b46fe953a3 Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan.grewe@g-node.org>
Date: Mon, 11 Mar 2024 16:25:06 +0100
Subject: [PATCH] some notes, infrastructure for dualcam grabbing

---
 notes.md          |  26 +++-
 pylonrecorder.cpp | 321 ++++++++++++++++++++++++++--------------------
 pylonrecorder.h   |  20 ++-
 3 files changed, 221 insertions(+), 146 deletions(-)

diff --git a/notes.md b/notes.md
index c5f6721..f6d2daf 100644
--- a/notes.md
+++ b/notes.md
@@ -3,12 +3,34 @@
 Recorder for up to two Basler cameras.
 
 ## TODOs
+
 * implement grabbing from 2 joined cameras
 * set the region of interest
 * save properly
 
-## FIXMEs & improvements
+## FIXMEs
 
-* make the max image sizes depend on camera
+* dualcamwrapper: remove hardcode
+* dualcamwrapper: support setting exposure individually
+* dualcamwrapper: support setting gain individually
+* pylonrecorder somehow remembers the old layout:
+* display of images during recording of both cameras.
+* 
 
+## Improvements
 
+* make the max image sizes depend on camera
+* detect framedrops based on the framecounts
+* support reading out camera health (temperature)
+* add interface to change camera DeviceUserID to provided an user friendly name for the cameras
+* code cleanup check import guards
+* check private public 
+* add interface for single- dual- multi-camera support
+* same for grabbing from single or multiple devices
+* support handling of multiple buffers in GUI (load, pessure)
+* remove the old open, save etc. functions.
+* improve dry run to not create panik by showing the buffer lad to go up
+* support buffer progress for two cams/buffers
+* add functionality to adjust the gain per camera (automatically?)
+* cleanup setter function on dual and single camera wrappers...
+* remove full name from SinglecamWrapper
\ No newline at end of file
diff --git a/pylonrecorder.cpp b/pylonrecorder.cpp
index 298cfbc..9992c8e 100644
--- a/pylonrecorder.cpp
+++ b/pylonrecorder.cpp
@@ -32,7 +32,12 @@
 #endif
 
 PylonRecorder::PylonRecorder(QWidget *parent)
-  : QMainWindow(parent), imageLabel(new QLabel), scrollArea(new QScrollArea), grabber(nullptr), writer(nullptr), buffer(nullptr), pyloncam(nullptr), dryRun(false), cameraOpened(false)
+  : QMainWindow(parent), imageLabel(new QLabel), scrollArea(new QScrollArea),
+    singlecamgrabber(nullptr), dualcamgrabber(nullptr), 
+    writer0(nullptr), writer1(nullptr),
+    buffer0(nullptr), buffer1(nullptr), 
+    singlecam(nullptr), dualcam(nullptr),
+    dryRun(false), cameraOpened(false), camsconfigured(false)
 {
   imageLabel->setBackgroundRole(QPalette::Base);
   imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
@@ -42,24 +47,7 @@ PylonRecorder::PylonRecorder(QWidget *parent)
   scrollArea->setWidget(imageLabel);
   scrollArea->setVisible(false);
   setCentralWidget(scrollArea);
-  // Pylon::DeviceInfoList_t deviceList = detectCameras();
-  // for (auto dev : deviceList) {
-  //   std::cout << dev.GetFullName() << " " << dev.GetFriendlyName() << std::endl;
-  // }
-  // std::cout << "peng\n";
-  // std::cout << deviceList.size() << std::endl;
-  // std::cout << "peng\n";
-
-  // if (deviceList.size() == 0) {
-  //   QErrorMessage message(this);
-  //   message.showMessage("No camera detected!");
-  // } else {
-  //   std::cout << "peng\n";
-  //   buffer = new ImageBuffer(defaultBufferSize);
-  //   grabber = new Grabber(pyloncam, buffer, defaultFrameRate);
-  //   writer = new Writer(buffer);
-  //   connect(writer, &Writer::writingDone, this, &PylonRecorder::writerDone);
-  // } 
+
   frameTimer = new QTimer(this);
   connect(frameTimer, &QTimer::timeout, this, &PylonRecorder::displaySingleFrame);
   pressureTimer = new QTimer(this);
@@ -118,34 +106,6 @@ PylonRecorder::PylonRecorder(QWidget *parent)
   applySettings();
 }
 
-// void PylonRecorder::setupCameras(){
-//   std::cerr << "Setting up cameras!" << std::endl;
-//   qDebug() << "setting up cameras";
-//   for (auto dev : deviceList) {
-//     std::cout << dev.GetFullName() << " " << dev.GetFriendlyName() << std::endl;
-//   }
-//   std::string s = "detected ";
-//   s += deviceList.size();
-//   s += " devices";
-//   qDebug() << s.c_str();
-
-//   if (deviceList.size() == 0) {
-//     qWarning() << "device list is empty!";
-//     QErrorMessage message(this);
-//     message.showMessage("No camera detected!");
-//   } else {
-//     std::cout << "peng\n";
-//     std::string cname = (std::string)deviceList[0].GetFullName(); 
-//     // qDebug() <<
-//     // pyloncam = new PylonWrapper(cname);
-//     qDebug() << "Creating buffer, grabber, and writer";
-//     buffer = new ImageBuffer(defaultBufferSize);
-//     grabber = new Grabber(pyloncam, buffer, defaultFrameRate);
-//     writer = new Writer(buffer);
-//     connect(writer, &Writer::writingDone, this, &PylonRecorder::writerDone);
-//   } 
-// }
-
 void PylonRecorder::detectCameras() {
   qDebug() << "Detecting devices!";
   Pylon::CTlFactory& TlFactory = Pylon::CTlFactory::GetInstance();
@@ -155,30 +115,56 @@ void PylonRecorder::detectCameras() {
 
 PylonRecorder::~PylonRecorder(){
   qDebug() << "Destructing PylonRecorder";
-  if (grabber != nullptr && grabber->isRunning()) { 
-      grabber->requestStop();
-      grabber->wait(1000);
+  if (singlecamgrabber != nullptr && singlecamgrabber->isRunning()) { 
+      singlecamgrabber->requestStop();
+      singlecamgrabber->wait(1000);
   }
-  if (writer != nullptr && writer->isRunning()) {
-      writer->forceStop();
-      writer->wait(1000);
+  if (writer0 != nullptr && writer0->isRunning()) {
+      writer0->forceStop();
+      writer0->wait(1000);
   }
   storeSettings();
-  if (pyloncam != nullptr) {
-    qDebug() << "Deleting pyloncam";
-    delete pyloncam;
-    pyloncam = nullptr;
+  if (singlecam != nullptr) {
+    qDebug() << "Deleting singlecam";
+    delete singlecam;
+    singlecam = nullptr;
+  }
+  if (dualcam != nullptr) {
+    qDebug() << "Deleting dualcam";
+    delete dualcam;
+    dualcam = nullptr;
   }
 
-  if (buffer != nullptr) {
+  if (buffer0 != nullptr) {
+    qDebug() << "Deleting buffer";
+    delete buffer0;
+    buffer0 = nullptr;
+  }
+  if (buffer1 != nullptr) {
     qDebug() << "Deleting buffer";
-    delete buffer;
-    buffer = nullptr;
+    delete buffer1;
+    buffer1 = nullptr;
+  }
+  if (singlecamgrabber != nullptr) {
+    qDebug() << "Deleting grabber";
+    delete singlecamgrabber;
+    singlecamgrabber = nullptr;
+  }
+  if (dualcamgrabber != nullptr) {
+    qDebug() << "Deleting grabber";
+    delete dualcamgrabber;
+    dualcamgrabber = nullptr;
+  }
+  if (writer0 != nullptr) {
+    qDebug() << "Deleting writer";
+    delete writer0;
+    writer0 = nullptr;
+  }
+  if (writer1 != nullptr) {
+    qDebug() << "Deleting writer";
+    delete writer1;
+    writer1 = nullptr;
   }
-  qDebug() << "Deleting grabber";
-  delete grabber;
-  qDebug() << "Deleting writer";
-  delete writer;
   qDebug() << "Deleting setting";
   delete settings;
 }
@@ -201,6 +187,7 @@ void PylonRecorder::applySettings() {
 
 
 void PylonRecorder::storeSettings() {
+  // FIXME store cam layout to settings
   settings->setValue("camera/exposure", exposureSpinner->value());
   settings->setValue("camera/framerate", framerateSpinner->value());
   settings->setValue("camera/gain", gainSpinner->value());
@@ -232,6 +219,7 @@ bool PylonRecorder::loadFile(const QString &fileName) {
 
 
 void PylonRecorder::setImage(const QImage &newImage) {
+  //FIXME figure out how to display both images. extract to extra class...
   image = newImage;
   // (image.colorSpace().isValid())
   //  image.convertToColorSpace(QColorSpace::SRgb);
@@ -563,6 +551,7 @@ void PylonRecorder::updateActions() {
   connect_camera_action->setEnabled(true);
   grab_still_action->setEnabled(deviceList.size() > 0);
   grab_continuous_action->setEnabled(cameraOpened && !grabbing);
+  // grab_continuous_action->setEnabled(!grabbing);
   grab_stop_action->setEnabled(grabbing);
 }
 
@@ -604,19 +593,30 @@ void PylonRecorder::adjustScrollBar(QScrollBar *scrollBar, double factor) {
                           + ((factor - 1) * scrollBar->pageStep()/2)));
 }
 
+
 void PylonRecorder::cameraConfiguration(){
     d = new CamConfigurator(deviceList, this);
-    connect(d, SIGNAL(accepted()), SLOT(camerasetup()));
+    connect(d, SIGNAL(accepted()), SLOT(cameraConfigurationAccepted()));
+    connect(d, SIGNAL(rejected()),  SLOT(cameraConfigurationAborted()));
     // QObject::connect(&d, SIGNAL(column_visibility_changed(QString, QString,bool)), this, SLOT(visible_columns_update(QString, QString,bool)));
     d->exec();
 }
 
-void PylonRecorder::camerasetup() {
+
+void PylonRecorder::cameraConfigurationAccepted() {
   qDebug() << "Cameras setting " << ((d->result()) ? "Accepted" : "Discarded");
   this->layout = d->layout();
+  camsconfigured = true;
   delete d;
 }
 
+
+void PylonRecorder::cameraConfigurationAborted() {
+  qDebug() << "Camera configuration aborted!";
+  camsconfigured = false;
+}
+
+
 void PylonRecorder::connectCamera() {
   this->layout = CameraLayout();
   std::cerr << this->layout.rois.size() << " " << this->layout.devices.size() << std::endl;
@@ -627,29 +627,54 @@ void PylonRecorder::connectCamera() {
     QString msg = "<p><b>No camera device found!</b></p><br><p>Connect camera and try again!</p>";
     msgBox.setText(msg);
     msgBox.exec();
-  } else {
-    cameraConfiguration();
-    if (layout.mode == CameraMode::single && layout.devices.size() == 1) {
-      qDebug() << "single camera mode";
-      std::string cname = layout.devices[0];
-      std::string message;
-      qDebug() << "connecting to camera " << cname.c_str();
-      pyloncam = new PylonWrapper(layout);
-      bool success = pyloncam->openCamera(message);
-      if (success) {
-        cameraConnectedLabel->setText("connected");
-        cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: green;}");
-        cameraOpened = true;
-      } else {
-        QMessageBox msgBox;
-        QString msg = "<p><b>Could not open camera device!</b><p><p>" + QString::fromStdString(message) + "</p>";
-        msgBox.setText(msg);
-        msgBox.exec();
-        cameraOpened = false;
-      }
-      statusBar()->showMessage(QString::fromStdString(message));
-      updateActions();
+    qWarning() << msg.toStdString().c_str();
+    return;
+  }
+  cameraConfiguration();
+  if (!camsconfigured) {
+    qDebug() << "cameras have not been properly configured!";
+    return;
+  }
+  if (layout.mode == CameraMode::single && layout.devices.size() == 1) {
+    qDebug() << "single camera mode";
+    std::string cname = layout.devices[0];
+    std::string message;
+    qDebug() << "connecting to camera " << cname.c_str();
+    singlecam = new PylonWrapper(layout);
+    bool success = singlecam->openCamera(message);
+    if (success) {
+      cameraConnectedLabel->setText("connected");
+      cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: green;}");
+      cameraOpened = true;
+    } else {
+      QMessageBox msgBox;
+      QString msg = "<p><b>Could not open camera device!</b><p><p>" + QString::fromStdString(message) + "</p>";
+      msgBox.setText(msg);
+      msgBox.exec();
+      cameraOpened = false;
     }
+    statusBar()->showMessage(QString::fromStdString(message));
+    updateActions();
+  }
+  if (layout.mode == CameraMode::dual && layout.devices.size() == 2) {
+    qDebug() << "dual camera mode";
+    std::string message;
+    qDebug() << "creating dual cam wrapper";
+    dualcam = new DualcamWrapper(layout);
+    bool success = dualcam->openCameras(message);
+    if (success) {
+      cameraConnectedLabel->setText("connected");
+      cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: green;}");
+      cameraOpened = true;
+    } else {
+      QMessageBox msgBox;
+      QString msg = "<p><b>Could not open camera device!</b><p><p>" + QString::fromStdString(message) + "</p>";
+      msgBox.setText(msg);
+      msgBox.exec();
+      cameraOpened = false;
+    }
+    statusBar()->showMessage(QString::fromStdString(message));
+    updateActions();
   }
   qDebug() << "connecting cam(s) done!";
 }
@@ -657,13 +682,18 @@ void PylonRecorder::connectCamera() {
 
 void PylonRecorder::disconnectCamera() {
   qDebug() << "disconnecting camera";
-  if (pyloncam != nullptr && pyloncam->isOpen()) {
-    pyloncam->closeCamera();
-    statusBar()->showMessage(tr("Camera closed!"));
-    cameraConnectedLabel->setText("not connected");
-    cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: red;}");
-    updateActions();
+  if (singlecam != nullptr && singlecam->isOpen()) {
+    singlecam->closeCamera();
+  }
+  if (dualcam != nullptr && dualcam->isOpen()) {
+    dualcam->closeCameras();
   }
+  statusBar()->showMessage(tr("Camera closed!"));
+  cameraConnectedLabel->setText("not connected");
+  cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: red;}");
+  updateActions();
+  camsconfigured = false;
+  cameraOpened = false;
   qDebug() << "disconnecting cameras done";
 }
 
@@ -687,13 +717,14 @@ VideoSpecs PylonRecorder::getVideoSpecs(const ImageSettings &settings) {
   return s;
 }
 
-void PylonRecorder::startRecording() {
+
+void PylonRecorder::startSinglecamRecording() {
   qDebug() << "start recording!";
   std::string filename = createFilename(".mp4");
   fileLabel->setText(QString::fromStdString(filename));
   qDebug() << "storing to file " << filename.c_str();
 
-  ImageSettings settings = pyloncam->getImageSettings();
+  ImageSettings settings = singlecam->getImageSettings();
   qDebug() << "got image settings";
 
   VideoSpecs specs = getVideoSpecs(settings);
@@ -701,54 +732,70 @@ void PylonRecorder::startRecording() {
   specs.format = VideoFormat::mp4;
   qDebug() << "got video specifications";
 
-  if (buffer != nullptr) {
-    buffer->clear();
-    delete buffer;
-    buffer = nullptr;
+  if (buffer0 != nullptr) {
+    buffer0->clear();
+    delete buffer0;
+    buffer0 = nullptr;
   }
   qDebug() << "setting image buffer to size " << buffersizeSpinner->value();
-  buffer = new ImageBuffer(defaultBufferSize);
-  if (buffersizeSpinner->value() != static_cast<int>(buffer->capacity())) {
-    buffer->resize(static_cast<size_t>(buffersizeSpinner->value()));
+  buffer0 = new ImageBuffer(defaultBufferSize);
+  if (buffersizeSpinner->value() != static_cast<int>(buffer0->capacity())) {
+    buffer0->resize(static_cast<size_t>(buffersizeSpinner->value()));
     loadBar->setRange(0, buffersizeSpinner->value());
   }
 
   qDebug() << "setting up grabber";
-  if (grabber != nullptr) {
-    delete grabber;
-    grabber = nullptr;
+  if (singlecamgrabber != nullptr) {
+    delete singlecamgrabber;
+    singlecamgrabber = nullptr;
   }
-  grabber = new Grabber(pyloncam, buffer, defaultFrameRate);
+  singlecamgrabber = new Grabber(singlecam, buffer0, defaultFrameRate);
   
-  if (framerateSpinner->value() != grabber->currentFramerate())
-    grabber->setFrameRate(framerateSpinner->value());
-  if (exposureSpinner->value() != int(grabber->currentExposureTime()))
-      grabber->setExposureTime(static_cast<double>(exposureSpinner->value()));
-  if (gainSpinner->value() != int(grabber->currentGain()))
-      grabber->setGain(static_cast<double>(gainSpinner->value()));
+  if (framerateSpinner->value() != singlecamgrabber->currentFramerate())
+    singlecamgrabber->setFrameRate(framerateSpinner->value());
+  if (exposureSpinner->value() != int(singlecamgrabber->currentExposureTime()))
+      singlecamgrabber->setExposureTime(static_cast<double>(exposureSpinner->value()));
+  if (gainSpinner->value() != int(singlecamgrabber->currentGain()))
+      singlecamgrabber->setGain(static_cast<double>(gainSpinner->value()));
 
   qDebug() << "setup writer";
-  if (writer != nullptr) {
-    delete writer;
-    writer = nullptr;
+  if (writer0 != nullptr) {
+    delete writer0;
+    writer0 = nullptr;
   }
-  writer = new Writer(buffer);
-  connect(writer, &Writer::writingDone, this, &PylonRecorder::writerDone);
-  writer->setVideoSpecs(specs);
+  writer0 = new Writer(buffer0);
+  connect(writer0, &Writer::writingDone, this, &PylonRecorder::writerDone);
+  writer0->setVideoSpecs(specs);
 
   QSettings s;
   this->mdata.read(s);
-  writer->setProjectMetadata(mdata);
+  writer0->setProjectMetadata(mdata);
 
-  buffer->clear();
+  buffer0->clear();
   if (!dryRunCheckBox->isChecked()) {
-    writer->start();
+    writer0->start();
     writing = true;
   }
   dryRun = dryRunCheckBox->isChecked();
-  grabber->start();
+  singlecamgrabber->start();
   grabbing = true;
-  stopRequest = false;
+  stopRequest = false;  
+}
+
+
+void PylonRecorder::startDualcamRecording() {
+
+}
+
+
+void PylonRecorder::startRecording() {
+  if (layout.mode == CameraMode::single) {
+    startSinglecamRecording();
+  } else if (layout.mode == CameraMode::dual){
+    startDualcamRecording();
+  } else {
+    qDebug() << "invalid camera mode!";
+  }
 
   pressureTimer->start(50);
   frameTimer->start(100);
@@ -763,17 +810,17 @@ void PylonRecorder::stopRecording() {
       qDebug() << "StopRecording: stop frame timer!";
       frameTimer->stop();
       qDebug() << "StopRecording: stop grabber!";
-      if (grabber !=nullptr)
-        grabber->requestStop();
+      if (singlecamgrabber !=nullptr)
+        singlecamgrabber->requestStop();
       qDebug() << "StopRecording: stop writer!";
-      if (writer != nullptr)
-        writer->requestStop();
+      if (writer0 != nullptr)
+        writer0->requestStop();
       grabbing = false;
       stopRequest = true;
       grab_stop_action->setEnabled(false);
       qDebug() << "StopRecording: clear buffer!";
-      if(buffer != nullptr) {
-          buffer->clear();
+      if(buffer0 != nullptr) {
+          buffer0->clear();
           writerDone();
       }
   }
@@ -789,8 +836,8 @@ void PylonRecorder::writerDone() {
   labelTimer->stop();
   writingLabel->setStyleSheet(inactiveLabelStyle);
   grabbingLabel->setStyleSheet(inactiveLabelStyle);
-  grabber->wait(10000);
-  writer->wait(10000);
+  singlecamgrabber->wait(10000);
+  writer0->wait(10000);
   writing = false;
   updateActions();
   qInfo() << "writer is Done!";
@@ -807,7 +854,7 @@ void PylonRecorder::displayActivity() {
 void PylonRecorder::displaySingleFrame() {
   MyImage *img;
   size_t fc = 0;
-  img = buffer->readLast(fc);
+  img = buffer0->readLast(fc);
   if (img != nullptr){
     std::cerr << "display, last frame count " << fc << std::endl;
     QImage qimg(static_cast<uchar *>(img->data()), img->width(), img->height(), QImage::Format::Format_Grayscale8);
@@ -845,22 +892,22 @@ std::string PylonRecorder::createFilename(const std::string &extension) {
 
 
 void PylonRecorder::displayBufferPressure() {
-  int value = static_cast<int>(round(buffer->bufferPressure()));
+  int value = static_cast<int>(round(buffer0->bufferPressure()));
   pressureBar->setValue(value);
   QColor color = progressColor(value);
   progressPalette.setBrush(QPalette::Highlight, QBrush(color));
   pressureBar->setPalette(progressPalette);
 
-  int load = static_cast<int>(buffer->bufferLoad());
+  int load = static_cast<int>(buffer0->bufferLoad());
   loadBar->setValue(load);
 }
 
 
 void PylonRecorder::grabStillFromPylon() {
   qDebug() << "Grab still image form camera!";
-  if (pyloncam != nullptr && pyloncam->isOpen()) {
+  if (singlecam != nullptr && singlecam->isOpen()) {
       MyImage img;
-      bool valid = pyloncam->grabFrame(img);
+      bool valid = singlecam->grabFrame(img);
       if (valid) {
           QImage qimg(static_cast<uchar *>(img.data()), img.width(), img.height(),
                      QImage::Format::Format_Grayscale8);
diff --git a/pylonrecorder.h b/pylonrecorder.h
index 77b3715..9c9ebb5 100644
--- a/pylonrecorder.h
+++ b/pylonrecorder.h
@@ -8,8 +8,10 @@
 #include <QSettings>
 #include <pylon/PylonIncludes.h>
 #include "pylonwrapper.h"
+#include "dualcamwrapper.h"
 #include "imagebuffer.h"
 #include "grabber.h"
+#include "dualcamgrabber.h"
 #include "writer.h"
 #include "projectsettings.h"
 #include "camconfig.h"
@@ -66,7 +68,8 @@ private slots:
     void displayActivity();
     void writerDone();
     void selectStorageLocation();
-    void camerasetup();
+    void cameraConfigurationAccepted();
+    void cameraConfigurationAborted();
 
 private:
     void createActions();
@@ -81,6 +84,8 @@ private:
     std::string createFilename(const std::string &extension=".raw");
     void cameraConfiguration();
     VideoSpecs getVideoSpecs(const ImageSettings &settings);
+    void startSinglecamRecording();
+    void startDualcamRecording();
 
     bool saveFile(const QString &fileName);
     void setImage(const QImage &newImage);
@@ -88,7 +93,6 @@ private:
     void applyScaling();
     void adjustScrollBar(QScrollBar *scrollBar, double factor);
     void detectCameras();
-    // void setupCameras();
     int defaultBufferSize = 3000, defaultFrameRate = 30, movieCount = 0, defaultExposureTime = 6000, defaultGain=13;
     QSettings *settings = new QSettings;
     QImage image;
@@ -99,12 +103,14 @@ private:
     QProgressBar *loadBar;
     QScrollArea *scrollArea;
     double scaleFactor = 1;
-    PylonWrapper *pyloncam;
-    ImageBuffer *buffer;
-    Grabber *grabber;
-    Writer *writer;
+    PylonWrapper *singlecam;
+    DualcamWrapper *dualcam;
+    ImageBuffer *buffer0, *buffer1;
+    Grabber *singlecamgrabber;
+    DualcamGrabber *dualcamgrabber;
+    Writer *writer0, *writer1;
     CameraLayout layout;
-    bool grabbing, stopRequest, writing, labelSwitch, dryRun, cameraOpened;
+    bool grabbing, stopRequest, writing, labelSwitch, dryRun, cameraOpened, camsconfigured;
     QPalette progressPalette;
     QString activeLabelStyleHigh = "QLabel { font-size: 10pt;font-family: Arial; color : red; }";
     QString activeLabelStyleLow = "QLabel { font-size: 10pt;font-family: Arial; color : cmyk(0, 255, 255, 0, 50); }";