// The following two functions are very big. Lots of code is necessay for // dynamically build guis. void DisplayArea::setupChannels() { this->labelConnect->setClickable(false); QSettings settings; settings.beginGroup(setcon::DEVICE_GROUP); settings.beginGroup(settings.value(setcon::DEVICE_ACTIVE).toString()); if (settings.contains(setcon::DEVICE_PORT)) { // if there is a device we must enable the connect button. this->labelConnect->setClickable(true); // TODO: One could make this more intelligent and only create / delete // channels that are (no longer) needed. // remove all channels from the frame if there are any. Happens if the // user changes the device specs or chooses another one. for (auto f : this->channelFramesVec) { utils::clearLayout(f->layout()); this->frameChannels->layout()->removeWidget(f); delete (f); } // clear the vector this->channelFramesVec.clear(); this->chanwVector.clear(); // create the frames that control one channel for (int i = 1; i <= settings.value(setcon::DEVICE_CHANNELS).toInt(); i++) { std::shared_ptr<ChannelWidgets> chanw = std::make_shared<ChannelWidgets>(); QFrame *channelFrameContainer = new QFrame(); channelFrameContainer->setLayout(new QVBoxLayout()); channelFrameContainer->setObjectName("ch" + QString::number(i) + "Container"); // this is the container frame QString frameQss = QString("QFrame#%1 {border: 1px solid ") + globcon::GREENCOLOR + ";}"; channelFrameContainer->setStyleSheet( frameQss.arg(channelFrameContainer->objectName())); channelFrameContainer->layout()->setSpacing(0); channelFrameContainer->layout()->setContentsMargins(QMargins()); this->frameChannels->layout()->addWidget(channelFrameContainer); // now the frame for the electrical values V, A, W. QFrame *vawFrame = new QFrame(); vawFrame->setObjectName("ch" + QString::number(i) + "vawFrame"); QString vawFrameQss = QString("QFrame#%1 {border-bottom: 1px solid ") + globcon::GREENCOLOR + ";}"; vawFrame->setStyleSheet(vawFrameQss.arg(vawFrame->objectName())); QGridLayout *vawLayout = new QGridLayout(); vawFrame->setLayout(vawLayout); channelFrameContainer->layout()->addWidget(vawFrame); vawLayout->addWidget(new QLabel("CH" + QString::number(i)), 0, 0, 1, 0, Qt::AlignLeft); chanw->voltageActual = new QLabel("0.00"); QFont actualFont = chanw->voltageActual->font(); actualFont.setPointSize(20); chanw->voltageActual->setAlignment(Qt::AlignRight | Qt::AlignVCenter); chanw->voltageActual->setStyleSheet( QString("QLabel {padding-right: 0.5em;}")); chanw->voltageActual->setFont(actualFont); chanw->currentActual = new QLabel("0.000"); chanw->currentActual->setAlignment(Qt::AlignRight | Qt::AlignVCenter); chanw->currentActual->setStyleSheet( QString("QLabel {padding-right: 0.5em;}")); chanw->currentActual->setFont(actualFont); chanw->wattageActual = new QLabel("0.000"); chanw->wattageActual->setAlignment(Qt::AlignRight | Qt::AlignVCenter); chanw->wattageActual->setStyleSheet( QString("QLabel {padding-right: 0.5em;}")); chanw->wattageActual->setFont(actualFont); vawLayout->addWidget(chanw->voltageActual, 1, 0); vawLayout->addWidget(chanw->currentActual, 2, 0); vawLayout->addWidget(chanw->wattageActual, 3, 0); QLabel *vActualUnit = new QLabel("V"); vActualUnit->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Preferred); vActualUnit->setAlignment(Qt::AlignTop); QLabel *aActualUnit = new QLabel("A"); aActualUnit->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Preferred); aActualUnit->setAlignment(Qt::AlignTop); QLabel *wActualUnit = new QLabel("W"); wActualUnit->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Preferred); wActualUnit->setAlignment(Qt::AlignTop); vawLayout->addWidget(vActualUnit, 1, 1); vawLayout->addWidget(aActualUnit, 2, 1); vawLayout->addWidget(wActualUnit, 3, 1); QFrame *bottomContainer = new QFrame(); bottomContainer->setLayout(new QHBoxLayout()); channelFrameContainer->layout()->addWidget(bottomContainer); bottomContainer->layout()->setSpacing(0); bottomContainer->layout()->setContentsMargins(QMargins()); QFrame *setContainer = new QFrame(); setContainer->setObjectName("ch" + QString::number(i) + "setContainer"); QGridLayout *setContLayout = new QGridLayout(); setContainer->setLayout(setContLayout); QString setContainerQss = QString("QFrame#%1 {border-right: 1px solid ") + globcon::GREENCOLOR + ";}"; setContainer->setStyleSheet( setContainerQss.arg(setContainer->objectName())); chanw->voltageSet = new ClickableLabel("0.00"); chanw->currentSet = new ClickableLabel("0.000"); chanw->voltageSet->setAlignment(Qt::AlignRight | Qt::AlignVCenter); chanw->currentSet->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // Now the lambdas for the set widgets QObject::connect( chanw->voltageSet, &ClickableLabel::doubleClick, [this, chanw, i](QPoint pos, double value) { this->controlValuesDialog( std::move(pos), chanw->voltageSet, global_constants::LPQ_DATATYPE::SETVOLTAGE, value); if (this->valuesDialog->exec()) { emit this->doubleValueChanged( this->valuesDialogData->voltage, static_cast<int>( global_constants::LPQ_DATATYPE::SETVOLTAGE), i); } }); QObject::connect( chanw->currentSet, &ClickableLabel::doubleClick, [this, chanw, i](QPoint pos, double value) { this->controlValuesDialog( std::move(pos), chanw->currentSet, global_constants::LPQ_DATATYPE::SETCURRENT, value); if (this->valuesDialog->exec()) { emit this->doubleValueChanged( this->valuesDialogData->current, static_cast<int>( global_constants::LPQ_DATATYPE::SETCURRENT), i); } }); QLabel *setLabel = new QLabel("Set"); setLabel->setAlignment(Qt::AlignCenter); QLabel *voltageSetUnit = new QLabel("V"); QFont bottomUnitFont = voltageSetUnit->font(); bottomUnitFont.setPointSize(8); voltageSetUnit->setFont(bottomUnitFont); voltageSetUnit->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Preferred); voltageSetUnit->setAlignment(Qt::AlignTop); QLabel *currentSetUnit = new QLabel("A"); currentSetUnit->setFont(bottomUnitFont); currentSetUnit->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Preferred); currentSetUnit->setAlignment(Qt::AlignTop); setContLayout->addWidget(setLabel, 0, 0, 1, 0); setContLayout->addWidget(chanw->voltageSet, 1, 0); setContLayout->addWidget(voltageSetUnit, 1, 1); setContLayout->addWidget(chanw->currentSet, 2, 0); setContLayout->addWidget(currentSetUnit, 2, 1); QFrame *modeOutputContainer = new QFrame(); modeOutputContainer->setLayout(new QVBoxLayout()); modeOutputContainer->layout()->setSpacing(0); modeOutputContainer->layout()->setContentsMargins(QMargins()); QFrame *modeContainer = new QFrame(); modeContainer->setLayout(new QHBoxLayout()); modeContainer->setObjectName("ch" + QString::number(i) + "modeContainer"); QString modeContainerQss = QString("QFrame#%1 {border-bottom: 1px solid ") + globcon::GREENCOLOR + ";}"; modeContainer->setStyleSheet( modeContainerQss.arg(modeContainer->objectName())); QLabel *modeLabel = new QLabel("Mode"); chanw->modeActual = new QLabel("CV"); modeContainer->layout()->addWidget(modeLabel); modeContainer->layout()->addWidget(chanw->modeActual); QFrame *outputContainer = new QFrame(); outputContainer->setLayout(new QHBoxLayout()); QLabel *outputLabel = new QLabel("Output"); chanw->outputSet = new ClickableLabel("Off"); chanw->outputSet->setNoReturnValue(true); QObject::connect( chanw->outputSet, &ClickableLabel::doubleClickNoValue, [this, chanw, i]() { emit this->deviceControlValueChanged( static_cast<int>(global_constants::LPQ_CONTROL::OUTPUT), i); }); outputContainer->layout()->addWidget(outputLabel); outputContainer->layout()->addWidget(chanw->outputSet); modeOutputContainer->layout()->addWidget(modeContainer); modeOutputContainer->layout()->addWidget(outputContainer); bottomContainer->layout()->addWidget(setContainer); bottomContainer->layout()->addWidget(modeOutputContainer); this->channelFramesVec.push_back(channelFrameContainer); // move semantics are needed here because unique_ptr does not allow // copying what push_back actually does. this->chanwVector.push_back(std::move(chanw)); } } }