├── .gitignore ├── CustomWidgets.pro ├── GITImages └── MainWindow.png ├── README.md ├── batterywidget.cpp ├── batterywidget.h ├── charge.png ├── images.qrc ├── levelwidget.cpp ├── levelwidget.h ├── mainApp.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── sevensegmentclock.cpp ├── sevensegmentclock.h ├── tachometerwidget.cpp ├── tachometerwidget.h ├── thermometerwidget.cpp ├── thermometerwidget.h ├── widgetengine.cpp └── widgetengine.h /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /CustomWidgets.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | CONFIG += c++11 6 | 7 | # The following define makes your compiler emit warnings if you use 8 | # any Qt feature that has been marked deprecated (the exact warnings 9 | # depend on your compiler). Please consult the documentation of the 10 | # deprecated API in order to know how to port your code away from it. 11 | DEFINES += QT_DEPRECATED_WARNINGS 12 | 13 | # You can also make your code fail to compile if it uses deprecated APIs. 14 | # In order to do so, uncomment the following line. 15 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 | 18 | SOURCES += \ 19 | batterywidget.cpp \ 20 | levelwidget.cpp \ 21 | mainApp.cpp \ 22 | mainwindow.cpp \ 23 | sevensegmentclock.cpp \ 24 | tachometerwidget.cpp \ 25 | thermometerwidget.cpp \ 26 | widgetengine.cpp 27 | 28 | HEADERS += \ 29 | batterywidget.h \ 30 | levelwidget.h \ 31 | mainwindow.h \ 32 | sevensegmentclock.h \ 33 | tachometerwidget.h \ 34 | thermometerwidget.h \ 35 | widgetengine.h 36 | 37 | FORMS += \ 38 | mainwindow.ui 39 | 40 | # Default rules for deployment. 41 | qnx: target.path = /tmp/$${TARGET}/bin 42 | else: unix:!android: target.path = /opt/$${TARGET}/bin 43 | !isEmpty(target.path): INSTALLS += target 44 | 45 | RESOURCES += \ 46 | images.qrc 47 | -------------------------------------------------------------------------------- /GITImages/MainWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p-dobrzynski-dev/QtCustomWidgets/0268217a8f19ed1464e498ecfc67813083cdec7a/GITImages/MainWindow.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtCustomWidgets 2 | 3 | Set of custom displays created using **C++** and **QT**. 4 | 5 | Such as: 6 | 7 | * Tachometer 8 | * Battery percentage 9 | * Thermometer 10 | * Seven Segment Clock 11 | * Level Widget 12 | 13 | 14 | -------------------------------------------------------------------------------- /batterywidget.cpp: -------------------------------------------------------------------------------- 1 | #include "batterywidget.h" 2 | 3 | #include 4 | #include 5 | 6 | BatteryWidget::BatteryWidget(QWidget *) 7 | { 8 | maxValue = 100; 9 | } 10 | 11 | void BatteryWidget::resizeEvent(QResizeEvent *) 12 | { 13 | // Making widget aspect ratio 2:1 (Rectangle) 14 | widgetFrame = getFrame(); 15 | 16 | widgetFrame.setSize(QSize(widgetFrame.width(),widgetFrame.height()/2)); 17 | widgetFrame.moveTop(widgetFrame.center().y()); 18 | 19 | float scaleValue = 0.95; 20 | QSizeF mainBatteryFrameSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()); 21 | mainBatteryFrame.setSize(mainBatteryFrameSize); 22 | 23 | mainBatteryFrame.moveTopLeft(widgetFrame.topLeft()); 24 | 25 | QSizeF tipBatteryFrameSize = QSizeF(widgetFrame.width()/3,widgetFrame.height()/2); 26 | tipBatteryFrame.setSize(tipBatteryFrameSize); 27 | 28 | QPointF tipBatteryFramePoint = QPointF(widgetFrame.topRight().x()-tipBatteryFrameSize.width(), widgetFrame.topRight().y()+tipBatteryFrameSize.height()/2); 29 | tipBatteryFrame.moveTopLeft(tipBatteryFramePoint); 30 | 31 | 32 | float batteryLevelOffset = mainBatteryFrame.height()/20; 33 | QSizeF batteryLevelFrameSize = QSizeF(mainBatteryFrame.width() - 2*batteryLevelOffset, mainBatteryFrame.height() - 2*batteryLevelOffset); 34 | batteryLevelFrame.setSize(batteryLevelFrameSize); 35 | 36 | QPointF batteryFramePoint = QPointF(mainBatteryFrame.topLeft().x() + batteryLevelOffset,mainBatteryFrame.topLeft().y() + batteryLevelOffset); 37 | batteryLevelFrame.moveTopLeft(batteryFramePoint); 38 | } 39 | 40 | void BatteryWidget::validateValue(float newValue) { 41 | if ((newValue >= minValue) && (newValue <=maxValue)){ 42 | value = newValue; 43 | } else if (newValue < minValue) { 44 | value = minValue; 45 | } else if (newValue > maxValue) { 46 | value = maxValue; 47 | } else { 48 | return; 49 | } 50 | } 51 | 52 | 53 | void BatteryWidget::setChargingState(bool state) { 54 | isCharging = state; 55 | this->update(); 56 | this->repaint(); 57 | } 58 | 59 | bool BatteryWidget::getChargingState() { 60 | return isCharging; 61 | } 62 | 63 | void BatteryWidget::paintEvent(QPaintEvent *) 64 | { 65 | 66 | QPainter painter(this); 67 | painter.setRenderHint( QPainter::Antialiasing, true); 68 | painter.setRenderHint( QPainter::HighQualityAntialiasing, true); 69 | QPen pen = QPen(Qt::red); 70 | QBrush brush = QBrush(Qt::white); 71 | 72 | painter.setPen(pen); 73 | //Drawing battery frame 74 | 75 | float widgetCorner = widgetFrame.height()/15; 76 | 77 | QPainterPath FramePath; 78 | FramePath.setFillRule(Qt::WindingFill); 79 | FramePath.addRoundedRect(mainBatteryFrame,widgetCorner, widgetCorner); 80 | FramePath.addRoundedRect(tipBatteryFrame, widgetCorner,widgetCorner); 81 | FramePath = FramePath.simplified(); 82 | 83 | pen.setColor(Qt::gray); 84 | pen.setWidth(widgetFrame.width()/75); 85 | painter.setPen(pen); 86 | painter.drawPath(FramePath); 87 | 88 | painter.setBrush(QBrush(QColor("#44bd32"))); 89 | painter.setPen(Qt::NoPen); 90 | QRectF batteryLevelRect = QRectF(); 91 | QSize batterySizeRect = QSize(batteryLevelFrame.width() * value/maxValue, batteryLevelFrame.height()); 92 | batteryLevelRect.setSize(batterySizeRect); 93 | batteryLevelRect.moveTo(batteryLevelFrame.topLeft()); 94 | painter.drawRoundedRect(batteryLevelRect, widgetCorner,widgetCorner); 95 | 96 | pen.setColor(Qt::white); 97 | painter.setPen(pen); 98 | QFont textFont = QFont(); 99 | textFont.setPixelSize(widgetFrame.height()/3); 100 | painter.setFont(textFont); 101 | QFontMetricsF fm(textFont); 102 | QString percentageLevelString = QString("%1%").arg(value); 103 | float textWidth = fm.width(percentageLevelString); 104 | float textHeight = fm.height(); 105 | 106 | QPointF textPosition = QPointF(widgetFrame.center().x()-textWidth/2,widgetFrame.center().y()+textHeight/3); 107 | painter.drawText(textPosition, percentageLevelString); 108 | 109 | float chargerSize = widgetFrame.height() / 2; 110 | 111 | if (isCharging) { 112 | QPixmap pixmap(":/img/charge.png"); 113 | painter.drawPixmap(widgetFrame.center().x() - chargerSize*1.5, widgetFrame.top() + chargerSize/2 ,chargerSize,chargerSize,pixmap); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /batterywidget.h: -------------------------------------------------------------------------------- 1 | #ifndef BATTERYWIDGET_H 2 | #define BATTERYWIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | class BatteryWidget: public WidgetEngine 8 | { 9 | Q_OBJECT 10 | public: 11 | BatteryWidget(QWidget *parent = nullptr); 12 | bool getChargingState(); 13 | void setChargingState(bool state); 14 | private: 15 | 16 | QRectF widgetFrame; 17 | QRectF mainBatteryFrame; 18 | QRectF tipBatteryFrame; 19 | QRectF batteryLevelFrame; 20 | 21 | bool isCharging = false; 22 | 23 | void resizeEvent(QResizeEvent *event) override; 24 | void paintEvent(QPaintEvent *event) override; 25 | void validateValue(float newValue) override; 26 | }; 27 | 28 | #endif // BATTERYWIDGET_H 29 | -------------------------------------------------------------------------------- /charge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p-dobrzynski-dev/QtCustomWidgets/0268217a8f19ed1464e498ecfc67813083cdec7a/charge.png -------------------------------------------------------------------------------- /images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | charge.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /levelwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "levelwidget.h" 2 | 3 | # include 4 | # include 5 | # include 6 | 7 | 8 | LevelWidget::LevelWidget(QWidget *) 9 | { 10 | } 11 | 12 | void LevelWidget::resizeEvent(QResizeEvent *) { 13 | // Making widget aspect ratio 1:1 (Square) 14 | widgetFrame = getFrame(); 15 | 16 | float scaleValue = 0.75; 17 | QSizeF outsideCircleFrameSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()*scaleValue); 18 | outsideCircleFrame.setSize(outsideCircleFrameSize); 19 | outsideCircleFrame.moveCenter(widgetFrame.center()); 20 | 21 | scaleValue = 0.5; 22 | QSizeF insideCircleFrameSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()*scaleValue); 23 | insideCircleFrame.setSize(insideCircleFrameSize); 24 | insideCircleFrame.moveCenter(widgetFrame.center()); 25 | 26 | scaleValue = 0.1; 27 | QSizeF levelCircleFrameSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()*scaleValue); 28 | levelCircleFrame.setSize(levelCircleFrameSize); 29 | 30 | } 31 | 32 | void LevelWidget::setXAngle(double newValue){ 33 | if (( minAngle <= newValue) && (newValue <= maxAngle)) { 34 | xAngle = newValue; 35 | } else if (newValue < minAngle){ 36 | xAngle = minAngle; 37 | } else if (newValue > maxAngle) { 38 | xAngle = maxAngle; 39 | } else { 40 | return; 41 | } 42 | this->update(); 43 | this->repaint(); 44 | } 45 | 46 | void LevelWidget::setYAngle(double newValue){ 47 | if (( minAngle <= newValue) && (newValue <= maxAngle)) { 48 | yAngle = newValue; 49 | } else if (newValue < minAngle){ 50 | yAngle = minAngle; 51 | } else if (newValue > maxAngle) { 52 | yAngle = maxAngle; 53 | } else { 54 | return; 55 | } 56 | this->update(); 57 | this->repaint(); 58 | } 59 | 60 | float LevelWidget::getXAngle() { 61 | return xAngle; 62 | } 63 | 64 | float LevelWidget::getYAngle() { 65 | return yAngle; 66 | } 67 | 68 | void LevelWidget::paintEvent(QPaintEvent *){ 69 | QPainter painter(this); 70 | painter.setRenderHint(QPainter::Antialiasing); 71 | QPen pen = QPen(Qt::red); 72 | 73 | painter.setPen(pen); 74 | 75 | float outsideFrameWidth = widgetFrame.width()/35; 76 | pen.setColor(QColor("#4b4b4b")); 77 | pen.setWidth(outsideFrameWidth); 78 | painter.setPen(pen); 79 | QBrush brush = QBrush(QColor("#3ae374")); 80 | painter.setBrush(brush); 81 | 82 | painter.drawEllipse(widgetFrame); 83 | 84 | pen.setColor(QColor("#3d3d3d")); 85 | pen.setWidth(widgetFrame.width()/70); 86 | painter.setPen(pen); 87 | 88 | brush.setColor(Qt::white); 89 | painter.setBrush(brush); 90 | 91 | 92 | // Level circle position 93 | QPointF levelCirclePosition; 94 | 95 | if (xAngle == 0 && yAngle == 0) { 96 | levelCirclePosition = widgetFrame.center(); 97 | } else { 98 | double angle = atan(yAngle/xAngle); 99 | float xNewPos = widgetFrame.center().x() + cos(angle)* xAngle/(maxAngle) * (widgetFrame.width() - levelCircleFrame.width() - outsideFrameWidth)/2; 100 | float yNewPos = widgetFrame.center().y() + sin(angle)* yAngle/(maxAngle) * (widgetFrame.width() - levelCircleFrame.height() - outsideFrameWidth)/2; 101 | levelCirclePosition = QPointF(xNewPos,yNewPos); 102 | } 103 | 104 | levelCircleFrame.moveCenter(levelCirclePosition); 105 | 106 | painter.drawEllipse(levelCircleFrame); 107 | 108 | brush.setColor(Qt::transparent); 109 | painter.setBrush(brush); 110 | 111 | painter.drawEllipse(outsideCircleFrame); 112 | painter.drawEllipse(insideCircleFrame); 113 | 114 | 115 | } 116 | -------------------------------------------------------------------------------- /levelwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef LEVELWIDGET_H 2 | #define LEVELWIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | class LevelWidget :public WidgetEngine 8 | { 9 | Q_OBJECT 10 | public: 11 | LevelWidget(QWidget *parent = nullptr); 12 | float getXAngle(); 13 | float getYAngle(); 14 | void setXAngle(double); 15 | void setYAngle(double); 16 | private: 17 | QRectF widgetFrame; 18 | QRectF outsideCircleFrame; 19 | QRectF insideCircleFrame; 20 | QRectF levelCircleFrame; 21 | 22 | float xAngle = 0.0; 23 | float yAngle = 0.0; 24 | 25 | float minAngle = -10.0; 26 | float maxAngle = 10.0; 27 | 28 | void resizeEvent(QResizeEvent *event) override; 29 | void paintEvent(QPaintEvent *) override; 30 | 31 | protected: 32 | using WidgetEngine::setValue; 33 | }; 34 | 35 | #endif // LEVELWIDGET_H 36 | -------------------------------------------------------------------------------- /mainApp.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | 5 | 6 | MainWindow::MainWindow(QMainWindow *parent) 7 | : QMainWindow(parent) 8 | , ui(new Ui::MainWindow) 9 | { 10 | ui->setupUi(this); 11 | 12 | // Thermometer widget 13 | ui->thermometerLineEdit->setText(QString::number(ui->Thermometer->getValue())); 14 | connect(ui->updateThermometerButton, SIGNAL (clicked()),this, SLOT (updateThermometer())); 15 | 16 | // Battery widget 17 | ui->BatteryLineEdit->setText(QString::number(ui->Battery->getValue())); 18 | if (ui->Battery->getChargingState()) { 19 | ui->isChargingBatteryCheckBox->setCheckState(Qt::Checked); 20 | } else { 21 | ui->isChargingBatteryCheckBox->setCheckState(Qt::Unchecked); 22 | } 23 | connect(ui->updateBatteryButton, SIGNAL (clicked()),this, SLOT (updateBattery())); 24 | 25 | // Tachometer widget 26 | ui->tachometerValueLineEdit->setText(QString::number(ui->tachometer->getValue())); 27 | ui->tachometerMaxValueLineEdit->setText(QString::number(ui->tachometer->getMaxValue())); 28 | connect(ui->updateTachometerButton, SIGNAL (clicked()),this, SLOT (updateTachometer())); 29 | 30 | // Seven segment clock 31 | ui->sevenSegmentLineEdit->setText(QString::number(ui->SevenSegmentClockWidget->getValue())); 32 | connect(ui->updateSevenSegmentButton, SIGNAL (clicked()),this, SLOT (updateSevenSegment())); 33 | 34 | // Level 35 | ui->levelXValueLineEdit->setText(QString::number(ui->level->getXAngle())); 36 | ui->levelYValueLineEdit->setText(QString::number(ui->level->getYAngle())); 37 | connect(ui->updateLevelButton, SIGNAL (clicked()),this, SLOT (updateLevel())); 38 | } 39 | 40 | MainWindow::~MainWindow() 41 | { 42 | delete ui; 43 | } 44 | 45 | void MainWindow::updateThermometer(){ 46 | QString value = ui->thermometerLineEdit->text(); 47 | double doubleValue = value.toDouble(); 48 | ui->Thermometer->setValue(doubleValue); 49 | } 50 | 51 | void MainWindow::updateBattery(){ 52 | QString value = ui->BatteryLineEdit->text(); 53 | int intValue = value.toInt(); 54 | ui->Battery->setValue(intValue); 55 | 56 | if (ui->isChargingBatteryCheckBox->isChecked()) { 57 | ui->Battery->setChargingState(true); 58 | } else { 59 | ui->Battery->setChargingState(false); 60 | } 61 | } 62 | 63 | void MainWindow::updateTachometer(){ 64 | QString value = ui->tachometerValueLineEdit->text(); 65 | int intValue = value.toInt(); 66 | ui->tachometer->setValue(intValue); 67 | 68 | QString maxValue = ui->tachometerMaxValueLineEdit->text(); 69 | int intMaxValue = maxValue.toInt(); 70 | ui->tachometer->setMaxValue(intMaxValue); 71 | } 72 | 73 | void MainWindow::updateSevenSegment() { 74 | QString value = ui->sevenSegmentLineEdit->text(); 75 | int intValue = value.toInt(); 76 | ui->SevenSegmentClockWidget->setValue(intValue); 77 | } 78 | 79 | void MainWindow::updateLevel(){ 80 | QString xValue = ui->levelXValueLineEdit->text(); 81 | float floatXValue = xValue.toFloat(); 82 | ui->level->setXAngle(floatXValue); 83 | 84 | QString yValue = ui->levelYValueLineEdit->text(); 85 | float floatYValue = yValue.toFloat(); 86 | ui->level->setYAngle(floatYValue); 87 | } 88 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | QT_BEGIN_NAMESPACE 7 | namespace Ui { class MainWindow; } 8 | QT_END_NAMESPACE 9 | 10 | class MainWindow : public QMainWindow 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | MainWindow(QMainWindow *parent = nullptr); 16 | ~MainWindow(); 17 | 18 | private: 19 | Ui::MainWindow *ui; 20 | 21 | private slots: 22 | void updateThermometer(); 23 | void updateBattery(); 24 | void updateTachometer(); 25 | void updateSevenSegment(); 26 | void updateLevel(); 27 | }; 28 | #endif // MAINWINDOW_H 29 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 900 10 | 900 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 900 22 | 900 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | 31 | 0 32 | 0 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 7 segment clock 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 0 51 | 0 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Value 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 0 70 | 0 71 | 72 | 73 | 74 | 75 | 100 76 | 16777215 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | Update 85 | 86 | 87 | 88 | 89 | 90 | 91 | Qt::Vertical 92 | 93 | 94 | 95 | 20 96 | 40 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Level 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 0 121 | 0 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | X Value 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 0 140 | 0 141 | 142 | 143 | 144 | 145 | 100 146 | 16777215 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | Y Value 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 0 163 | 0 164 | 165 | 166 | 167 | 168 | 100 169 | 16777215 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | Update 178 | 179 | 180 | 181 | 182 | 183 | 184 | Qt::Vertical 185 | 186 | 187 | 188 | 20 189 | 40 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | Tahometer 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 0 214 | 0 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | Max Value 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 0 233 | 0 234 | 235 | 236 | 237 | 238 | 100 239 | 16777215 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | Value 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 0 256 | 0 257 | 258 | 259 | 260 | 261 | 100 262 | 16777215 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | Update 271 | 272 | 273 | 274 | 275 | 276 | 277 | Qt::Vertical 278 | 279 | 280 | 281 | 20 282 | 40 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | Thermometer 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 0 307 | 0 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | QLayout::SetDefaultConstraint 316 | 317 | 318 | 319 | 320 | Value 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 0 329 | 0 330 | 331 | 332 | 333 | 334 | 100 335 | 20 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | Update 347 | 348 | 349 | 350 | 351 | 352 | 353 | Qt::Vertical 354 | 355 | 356 | 357 | 20 358 | 40 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | Battery 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 0 383 | 0 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | Value 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 0 402 | 0 403 | 404 | 405 | 406 | 407 | 100 408 | 16777215 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | Is charging 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 0 425 | 0 426 | 427 | 428 | 429 | Update 430 | 431 | 432 | 433 | 434 | 435 | 436 | Qt::Vertical 437 | 438 | 439 | 440 | 20 441 | 40 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | TachometerWidget 461 | QWidget 462 |
tachometerwidget.h
463 | 1 464 |
465 | 466 | BatteryWidget 467 | QWidget 468 |
batterywidget.h
469 | 1 470 |
471 | 472 | SevenSegmentClock 473 | QWidget 474 |
sevensegmentclock.h
475 | 1 476 |
477 | 478 | LevelWidget 479 | QWidget 480 |
levelwidget.h
481 | 1 482 |
483 | 484 | ThermometerWidget 485 | QWidget 486 |
thermometerwidget.h
487 | 1 488 |
489 |
490 | 491 | 492 |
493 | -------------------------------------------------------------------------------- /sevensegmentclock.cpp: -------------------------------------------------------------------------------- 1 | #include "sevensegmentclock.h" 2 | 3 | #include 4 | #include 5 | 6 | SevenSegmentClock::SevenSegmentClock(QWidget *){ 7 | maxValue = 9999; 8 | } 9 | 10 | void SevenSegmentClock::resizeEvent(QResizeEvent *) { 11 | // Making widget aspect ratio 1:1 (Square) 12 | widgetFrame = getFrame(); 13 | } 14 | 15 | void SevenSegmentClock::validateValue(float newValue) { 16 | if (minValue <= newValue && newValue <= maxValue) { 17 | value = newValue; 18 | } else if (newValue < minValue){ 19 | value = minValue; 20 | } else if (newValue > maxValue) { 21 | value = maxValue; 22 | } 23 | } 24 | 25 | void SevenSegmentClock:: paintEvent(QPaintEvent *) { 26 | QPainter painter(this); 27 | painter.setRenderHint(QPainter::Antialiasing); 28 | QPen pen = QPen(Qt::red); 29 | QBrush brush = QBrush(Qt::white); 30 | 31 | painter.setPen(pen); 32 | painter.setBrush(brush); 33 | 34 | QList segmentsRects = calculateRectsForSegments(); 35 | QList digits = getListOfSingleDigitsFrom(value); 36 | 37 | for( int i=0; i singleSegment = getSingleSegment(segmentsRects[i], digits[i]); 40 | painter.setBrush(QBrush(Qt::green)); 41 | painter.setBrush(QBrush(Qt::red)); 42 | foreach(QRectF segment, singleSegment) { 43 | painter.drawRect(segment); 44 | } 45 | } 46 | 47 | } 48 | 49 | QList SevenSegmentClock::getListOfSingleDigitsFrom(int number) { 50 | QList listOfDigits = QList(); 51 | int tempNum; 52 | for (int i = 0; i<4; i++) { 53 | tempNum = number%10; 54 | number = number/10; 55 | listOfDigits.append(tempNum); 56 | } 57 | 58 | // Reversing list of digits 59 | for(int k = 0; k < (listOfDigits.size()/2); k++) listOfDigits.swapItemsAt(k,listOfDigits.size()-(1+k)); 60 | return listOfDigits; 61 | } 62 | 63 | QList SevenSegmentClock::calculateRectsForSegments(){ 64 | 65 | float spacing = widgetFrame.width()/20; 66 | 67 | float singleClockWidth = (widgetFrame.width() - 3 * spacing) / 4; 68 | float singleClockHeight = (widgetFrame.height() / 2); 69 | 70 | QList listOfRects = QList(); 71 | 72 | for (int i = 0; i< 4; i++) { 73 | QRectF tempRect = QRectF(QPointF(widgetFrame.left() + (singleClockWidth + spacing) * i, widgetFrame.topLeft().y()+singleClockHeight/2), QSize(singleClockWidth, singleClockHeight)); 74 | listOfRects.append(tempRect); 75 | } 76 | return listOfRects; 77 | } 78 | 79 | QList SevenSegmentClock::getSingleSegment(QRectF forRect, int number){ 80 | QList tempRects = QList(); 81 | 82 | float segmentWidth = widgetFrame.width()/20; 83 | 84 | float segmentVHeight = (forRect.height() - 3 * segmentWidth) / 2; 85 | 86 | QRectF ASegment = QRectF(forRect.topLeft(), QSize(forRect.width(),segmentWidth)); 87 | QRectF BSegment = QRectF(QPoint(forRect.topRight().x()-segmentWidth, forRect.topRight().y()+segmentWidth), QSize(segmentWidth,segmentVHeight)); 88 | QRectF CSegment = QRectF(QPoint(forRect.topRight().x()-segmentWidth, forRect.topRight().y()+segmentWidth*2+segmentVHeight), QSize(segmentWidth,segmentVHeight)); 89 | QRectF DSegment = QRectF(QPoint(forRect.bottomLeft().x(), forRect.bottomLeft().y()-segmentWidth), QSize(forRect.width(),segmentWidth)); 90 | QRectF ESegment = QRectF(QPoint(forRect.left(), forRect.top()+segmentWidth*2+segmentVHeight), QSize(segmentWidth,segmentVHeight)); 91 | QRectF FSegment = QRectF(QPoint(forRect.left(), forRect.top()+segmentWidth), QSize(segmentWidth,segmentVHeight)); 92 | QRectF GSegment = QRectF(QPoint(forRect.left(), forRect.top()+segmentWidth+segmentVHeight), QSize(forRect.width(),segmentWidth)); 93 | 94 | switch (number) { 95 | case 0: 96 | tempRects.append(ASegment); 97 | tempRects.append(BSegment); 98 | tempRects.append(CSegment); 99 | tempRects.append(DSegment); 100 | tempRects.append(ESegment); 101 | tempRects.append(FSegment); 102 | break; 103 | case 1: 104 | tempRects.append(BSegment); 105 | tempRects.append(CSegment); 106 | break; 107 | case 2: 108 | tempRects.append(ASegment); 109 | tempRects.append(BSegment); 110 | tempRects.append(GSegment); 111 | tempRects.append(ESegment); 112 | tempRects.append(DSegment); 113 | break; 114 | case 3: 115 | tempRects.append(ASegment); 116 | tempRects.append(BSegment); 117 | tempRects.append(GSegment); 118 | tempRects.append(CSegment); 119 | tempRects.append(DSegment); 120 | break; 121 | case 4: 122 | tempRects.append(FSegment); 123 | tempRects.append(BSegment); 124 | tempRects.append(GSegment); 125 | tempRects.append(CSegment); 126 | break; 127 | case 5: 128 | tempRects.append(ASegment); 129 | tempRects.append(FSegment); 130 | tempRects.append(GSegment); 131 | tempRects.append(CSegment); 132 | tempRects.append(DSegment); 133 | break; 134 | case 6: 135 | tempRects.append(ASegment); 136 | tempRects.append(FSegment); 137 | tempRects.append(GSegment); 138 | tempRects.append(CSegment); 139 | tempRects.append(DSegment); 140 | tempRects.append(ESegment); 141 | break; 142 | case 7: 143 | tempRects.append(ASegment); 144 | tempRects.append(BSegment); 145 | tempRects.append(CSegment); 146 | break; 147 | case 8: 148 | tempRects.append(ASegment); 149 | tempRects.append(BSegment); 150 | tempRects.append(CSegment); 151 | tempRects.append(DSegment); 152 | tempRects.append(ESegment); 153 | tempRects.append(FSegment); 154 | tempRects.append(GSegment); 155 | break; 156 | case 9: 157 | tempRects.append(ASegment); 158 | tempRects.append(BSegment); 159 | tempRects.append(CSegment); 160 | tempRects.append(DSegment); 161 | tempRects.append(FSegment); 162 | tempRects.append(GSegment); 163 | break; 164 | default: 165 | break; 166 | } 167 | 168 | return tempRects; 169 | 170 | } 171 | -------------------------------------------------------------------------------- /sevensegmentclock.h: -------------------------------------------------------------------------------- 1 | #ifndef SEVENSEGMENTCLOCK_H 2 | #define SEVENSEGMENTCLOCK_H 3 | 4 | #include 5 | #include 6 | 7 | class SevenSegmentClock : public WidgetEngine 8 | { 9 | Q_OBJECT 10 | public: 11 | SevenSegmentClock(QWidget *parent = nullptr); 12 | private: 13 | QRectF widgetFrame; 14 | void paintEvent(QPaintEvent *) override; 15 | void resizeEvent(QResizeEvent *event) override; 16 | void validateValue(float newValue) override; 17 | 18 | QList getSingleSegment(QRectF forRect, int number); 19 | QList calculateRectsForSegments(); 20 | QList getListOfSingleDigitsFrom(int number); 21 | }; 22 | 23 | #endif // SEVENSEGMENTCLOCK_H 24 | -------------------------------------------------------------------------------- /tachometerwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "tachometerwidget.h" 2 | 3 | # include 4 | # include 5 | # include 6 | 7 | TachometerWidget::TachometerWidget(QWidget *) 8 | { 9 | maxValue = 280; 10 | } 11 | 12 | void TachometerWidget:: resizeEvent(QResizeEvent *){ 13 | 14 | // Making widget aspect ratio 1:1 (Square) 15 | widgetFrame = getFrame(); 16 | 17 | //Setting inner arc rect 18 | float scaleValue = 0.85; 19 | QSizeF innerArcSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()*scaleValue); 20 | innerArcFrame.setSize(innerArcSize); 21 | 22 | QPointF innerArcOffsetPoint = getWidgetFrameOffset(innerArcSize); 23 | innerArcFrame.moveTopLeft(innerArcOffsetPoint); 24 | 25 | //Setting tip circle rect 26 | scaleValue = 0.1; 27 | QSizeF tipCircleSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()*scaleValue); 28 | tipCircleFrame.setSize(tipCircleSize); 29 | 30 | QPointF tipCircleOffsetPoint = getWidgetFrameOffset(tipCircleSize); 31 | tipCircleFrame.moveTopLeft(tipCircleOffsetPoint); 32 | 33 | //Setting tip rect 34 | scaleValue = 0.05; 35 | QSizeF tipSize = QSizeF(widgetFrame.width()*scaleValue,widgetFrame.height()/3); 36 | tipFrame.setSize(tipSize); 37 | 38 | QPointF tipOffsetPoint = QPointF(-tipSize.width()/2,-tipSize.height()); 39 | tipFrame.moveTopLeft(tipOffsetPoint); 40 | } 41 | 42 | 43 | float getRadians(float Degrees){ 44 | float radians = Degrees * M_PI / 180.; 45 | return radians; 46 | } 47 | 48 | 49 | void TachometerWidget::validateValue(float newValue) { 50 | if (newValue >= maxValue) { 51 | value = maxValue; 52 | } else if (newValue <= minValue) { 53 | value = minValue; 54 | } 55 | else { 56 | value = newValue; 57 | } 58 | } 59 | 60 | void TachometerWidget:: paintEvent(QPaintEvent *){ 61 | 62 | QPainter painter(this); 63 | painter.setRenderHint(QPainter::Antialiasing); 64 | QPen pen = QPen(Qt::red); 65 | QBrush brush = QBrush(Qt::white); 66 | 67 | painter.setPen(pen); 68 | 69 | //Drawing main circle 70 | float outPenWidth = widgetFrame.width()/50; 71 | 72 | pen.setWidthF(outPenWidth); 73 | pen.setColor(Qt::gray); 74 | painter.setPen(pen); 75 | painter.setBrush(brush); 76 | painter.drawEllipse(widgetFrame); 77 | 78 | 79 | //Drawing inner arc 80 | float innerPenWidth = widgetFrame.width()/75; 81 | pen.setWidthF(innerPenWidth); 82 | painter.setPen(pen); 83 | 84 | int startAngle = -45 * 16; 85 | int spanAngle = 270 * 16; 86 | painter.drawArc(innerArcFrame,startAngle,spanAngle); 87 | 88 | //Drawing tip 89 | 90 | painter.translate(this->width()/2,this->height()/2); 91 | painter.rotate((value/maxValue)*270-135); 92 | 93 | QPainterPath tipPath = QPainterPath(); 94 | QPointF tipOfTip = QPointF(tipFrame.left() + tipFrame.width()/2,tipFrame.top()); 95 | 96 | QPointF tipPoints[3] = {tipFrame.bottomLeft(),tipOfTip,tipFrame.bottomRight()}; 97 | 98 | pen.setColor(Qt::red); 99 | pen.setWidth(1); 100 | painter.setPen(pen); 101 | painter.setBrush(Qt::red); 102 | painter.drawPolygon(tipPoints,3); 103 | painter.resetTransform(); 104 | 105 | //Drawing tipcicle 106 | pen.setColor(Qt::NoPen); 107 | painter.setPen(pen); 108 | brush.setColor(Qt::black); 109 | painter.setBrush(brush); 110 | painter.drawEllipse(tipCircleFrame); 111 | 112 | //Drawing lines and numbers 113 | pen.setColor(Qt::red); 114 | painter.setPen(pen); 115 | 116 | int interval = 20; 117 | int numberOfLines = maxValue/interval; 118 | double degreesPerLine = double(270)/double(numberOfLines); 119 | QFont textFont = QFont(); 120 | textFont.setPixelSize(widgetFrame.height()/20); 121 | painter.setFont(textFont); 122 | 123 | for (int i = 0; i 5 | #include 6 | 7 | class TachometerWidget :public WidgetEngine 8 | { 9 | Q_OBJECT 10 | public: 11 | TachometerWidget(QWidget *parent = nullptr); 12 | private: 13 | 14 | QRectF widgetFrame; 15 | QRectF innerArcFrame; 16 | QRectF tipCircleFrame; 17 | QRectF tipFrame; 18 | 19 | void resizeEvent(QResizeEvent *event) override; 20 | void paintEvent(QPaintEvent *event) override; 21 | void validateValue(float newValue) override; 22 | }; 23 | 24 | #endif // TACHOMETERWIDGET_H 25 | -------------------------------------------------------------------------------- /thermometerwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "thermometerwidget.h" 2 | 3 | # include 4 | # include 5 | # include 6 | # include 7 | 8 | 9 | ThermometerWidget::ThermometerWidget(QWidget *) 10 | { 11 | minValue = -20; 12 | maxValue = 60; 13 | } 14 | 15 | void ThermometerWidget:: resizeEvent(QResizeEvent *){ 16 | 17 | // Making widget aspect ratio 1:1 (Square) 18 | widgetFrame = getFrame(); 19 | 20 | float scaleValue = 0.1; 21 | QSizeF topTankRectSize = QSizeF(widgetFrame.width()*scaleValue, widgetFrame.height()); 22 | tankRect.setSize(topTankRectSize); 23 | 24 | QPointF topTankPoint = QPointF(widgetFrame.center().x() - widgetFrame.width()*scaleValue/2, widgetFrame.top()); 25 | tankRect.moveTopLeft(topTankPoint); 26 | 27 | } 28 | 29 | void ThermometerWidget::validateValue(float newValue) { 30 | if ((newValue >= minValue) && (newValue <=maxValue)){ 31 | value = newValue; 32 | } else if (newValue < minValue) { 33 | value = minValue; 34 | } else if (newValue > maxValue) { 35 | value = maxValue; 36 | } else { 37 | return; 38 | } 39 | } 40 | 41 | void ThermometerWidget:: paintEvent(QPaintEvent *){ 42 | 43 | QPainter painter(this); 44 | painter.setRenderHint(QPainter::Antialiasing); 45 | QPen pen = QPen(Qt::red); 46 | QBrush brush = QBrush(Qt::white); 47 | 48 | painter.setPen(pen); 49 | 50 | float cornerRadius = widgetFrame.width()/60; 51 | 52 | // Infill Path 53 | QPainterPath infillPath; 54 | QRectF infillRect = QRectF(tankRect); 55 | 56 | float stepHeightValue = widgetFrame.height()/(maxValue - minValue); 57 | infillRect.setTop(widgetFrame.top() - value*stepHeightValue + maxValue*stepHeightValue); 58 | infillPath.addRoundedRect(infillRect,cornerRadius,cornerRadius); 59 | pen.setColor(Qt::transparent); 60 | painter.setPen(pen); 61 | 62 | if (value > 0) { 63 | painter.fillPath(infillPath,Qt::red); 64 | } else { 65 | painter.fillPath(infillPath,Qt::blue); 66 | } 67 | painter.drawPath(infillPath); 68 | 69 | // Drawing tank 70 | painter.drawRect(tankRect); 71 | 72 | 73 | QPainterPath path; 74 | path.addRoundedRect(tankRect, cornerRadius,cornerRadius); 75 | 76 | pen.setColor(QColor("#2f3640")); 77 | pen.setWidth(widgetFrame.width()/80); 78 | painter.setPen(pen); 79 | painter.fillPath(path,Qt::transparent); 80 | painter.drawPath(path); 81 | 82 | // Drawing thermometer value 83 | QFont font = painter.font(); 84 | font.setPointSize(widgetFrame.height()/10); 85 | QFontMetrics fm(font); 86 | int textHeight = fm.height(); 87 | painter.setFont(font); 88 | painter.drawText(QPointF(widgetFrame.center().x() - widgetFrame.width()/2,tankRect.topRight().y()+textHeight), QString("%1°C").arg(QString::number(value,'f',1))); 89 | 90 | // Drawing lines 91 | pen.setWidth(widgetFrame.width()/100); 92 | painter.setPen(pen); 93 | 94 | int numberOfLines = (maxValue - minValue) / 10; 95 | 96 | float lineInterval = tankRect.height()/numberOfLines; 97 | 98 | for (int i = 1; i < numberOfLines; i++) { 99 | 100 | if (i == 6) { 101 | pen.setWidth(widgetFrame.width()/50); 102 | painter.setPen(pen); 103 | } else { 104 | pen.setWidth(widgetFrame.width()/100); 105 | painter.setPen(pen); 106 | } 107 | QPointF lineBegining = QPointF(tankRect.center().x()-tankRect.width()/1.5,widgetFrame.top() + lineInterval * i); 108 | QPointF lineEnding = QPointF(tankRect.center().x()+tankRect.width()/1.5,widgetFrame.top() + lineInterval * i); 109 | QLineF line = QLineF(lineBegining,lineEnding); 110 | painter.drawLine(line); 111 | painter.drawText(QPointF(lineEnding.x()+widgetFrame.width()/20,lineEnding.y()),QString("%1").arg(maxValue - 10*i)); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /thermometerwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef THERMOMETERWIDGET_H 2 | #define THERMOMETERWIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | class ThermometerWidget : public WidgetEngine 8 | { 9 | Q_OBJECT 10 | public: 11 | ThermometerWidget(QWidget *parent = nullptr); 12 | private: 13 | QRectF widgetFrame; 14 | QRectF tankRect; 15 | 16 | void paintEvent(QPaintEvent *) override; 17 | void resizeEvent(QResizeEvent *event) override; 18 | void validateValue(float newValue) override; 19 | }; 20 | 21 | #endif // THERMOMETERWIDGET_H 22 | -------------------------------------------------------------------------------- /widgetengine.cpp: -------------------------------------------------------------------------------- 1 | #include "widgetengine.h" 2 | #include 3 | 4 | 5 | WidgetEngine::WidgetEngine(QWidget *parent) : 6 | QWidget(parent) 7 | { 8 | 9 | } 10 | 11 | QRectF WidgetEngine::getFrame() { 12 | QRectF frame = QRectF(); 13 | QSizeF newWidgetSize; 14 | // Making widget aspect ratio 1:1 (Square) 15 | if (this->width() > this->height()){ 16 | newWidgetSize = QSizeF(this->height()*0.95,this->height()*0.95); 17 | frame.setSize(newWidgetSize); 18 | 19 | QPointF widgetFrameOffsetPoint = getWidgetFrameOffset(newWidgetSize); 20 | frame.moveTopLeft(widgetFrameOffsetPoint); 21 | }else { 22 | newWidgetSize = QSizeF(this->width()*0.95,this->width() * 0.95); 23 | frame.setSize(newWidgetSize); 24 | 25 | QPointF widgetOffsetPoint = getWidgetFrameOffset(newWidgetSize); 26 | frame.moveTopLeft(widgetOffsetPoint); 27 | } 28 | return frame; 29 | } 30 | 31 | QPointF WidgetEngine::getWidgetFrameOffset(QSizeF newWidgetSize){ 32 | float xOffset = this->width()/2-newWidgetSize.width()/2; 33 | float yOffset = this->height()/2-newWidgetSize.height()/2; 34 | 35 | return QPointF(xOffset,yOffset); 36 | } 37 | 38 | void WidgetEngine::validateValue(float newValue) { 39 | value = newValue; 40 | } 41 | 42 | void WidgetEngine::setValue(float newValue) { 43 | validateValue(newValue); 44 | this->update(); 45 | this->repaint(); 46 | } 47 | 48 | float WidgetEngine::getValue() { 49 | return value; 50 | } 51 | 52 | void WidgetEngine::setMaxValue(float newMaxValue){ 53 | maxValue = newMaxValue; 54 | this->update(); 55 | this->repaint(); 56 | } 57 | 58 | float WidgetEngine::getMaxValue() { 59 | return maxValue; 60 | } 61 | -------------------------------------------------------------------------------- /widgetengine.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGETENGINE_H 2 | #define WIDGETENGINE_H 3 | 4 | #include 5 | #include 6 | 7 | class WidgetEngine: public QWidget 8 | { 9 | public: 10 | explicit WidgetEngine(QWidget *parent = nullptr); 11 | QRectF getFrame(); 12 | QPointF getWidgetFrameOffset(QSizeF newWidgetSize); 13 | void setValue(float newValue); 14 | void setMaxValue(float maxValue); 15 | float value = 0; 16 | float maxValue = 0; 17 | float minValue = 0; 18 | 19 | float getValue(); 20 | float getMaxValue(); 21 | float getMinValue(); 22 | 23 | private: 24 | virtual void validateValue(float newValue); 25 | }; 26 | 27 | #endif // WIDGETENGINE_H 28 | --------------------------------------------------------------------------------