From 906a0cc4a80e1f7e675745cf9f93899e927cd09f Mon Sep 17 00:00:00 2001 From: JC Luna Date: Wed, 1 Apr 2026 15:46:17 -0500 Subject: [PATCH 1/5] Composite Dial use initializer list --- src/Widgets/Dial/Attitude.cpp | 3 ++- src/Widgets/Dial/Composite.cpp | 20 +++++++++----------- src/Widgets/Dial/Composite.hpp | 2 +- src/Widgets/Displays/RateLabel.cpp | 4 +++- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Widgets/Dial/Attitude.cpp b/src/Widgets/Dial/Attitude.cpp index 022f309..0225c90 100644 --- a/src/Widgets/Dial/Attitude.cpp +++ b/src/Widgets/Dial/Attitude.cpp @@ -4,7 +4,8 @@ namespace VSCL { -AttitudeDial::AttitudeDial(QWidget* parent) : QWidget(parent) { +AttitudeDial::AttitudeDial(QWidget* parent) + : QWidget(parent) { SetRangeType(RangeTypeMode); update(); } // AttitudeDial ctor diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index 9f262a0..cec166a 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -2,17 +2,20 @@ namespace VSCL { -CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { +CompositeDial::CompositeDial(QWidget* parent) + : QWidget(parent) + , MajorOrganizer(new QGridLayout(this)) + , DialNameLabel(new QLabel(this)) + , DialRateDuo(new QWidget(this)) + , DuoOrganizer(new QGridLayout(DialRateDuo)) + , Dial(new AttitudeDial(DialRateDuo)) + , NumericRateLabel(new RateLabel(DialRateDuo)) { + // Widget setup goes top -> bottom level - // Top-level - MajorOrganizer = new QGridLayout(this); this->setLayout(MajorOrganizer); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - DialNameLabel = new QLabel(this); - DialRateDuo = new QWidget(this); - MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); @@ -25,14 +28,9 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { DialNameLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); DialNameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); - // Bottom-level - DuoOrganizer = new QGridLayout(DialRateDuo); DialRateDuo->setLayout(DuoOrganizer); - Dial = new AttitudeDial(DialRateDuo); - NumericRateLabel = new RateLabel(DialRateDuo); - DuoOrganizer->addWidget(Dial, 0, 0); DuoOrganizer->addWidget(NumericRateLabel, 0, 0); diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index ffb41d7..f3ccf1d 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -32,8 +32,8 @@ class CompositeDial : public QWidget { QFont DialNameFont{ }; Util::FontAdjustment TitleAdjustment{ 16, false }; - QGridLayout* DuoOrganizer; QWidget* DialRateDuo; + QGridLayout* DuoOrganizer; AttitudeDial* Dial; RateLabel* NumericRateLabel; diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp index 37243fe..5a3244e 100644 --- a/src/Widgets/Displays/RateLabel.cpp +++ b/src/Widgets/Displays/RateLabel.cpp @@ -5,7 +5,9 @@ #include "Util/FiniteDiff.hpp" namespace VSCL { -RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { +RateLabel::RateLabel(QWidget* parent) + : QLabel(parent) { + SetTextFrom(0.0); setFrameStyle(QFrame::StyledPanel | QFrame::Plain); setStyleSheet("background-color: white;" From 2c0b88bbcec42f47f3026d4c8da8fdd3a45a25b7 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Wed, 1 Apr 2026 16:16:17 -0500 Subject: [PATCH 2/5] Reorganize composite's constructor for ore obvious alignment and parenting stuff --- src/Widgets/Dial/Composite.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index cec166a..a3f1e3b 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -11,34 +11,32 @@ CompositeDial::CompositeDial(QWidget* parent) , Dial(new AttitudeDial(DialRateDuo)) , NumericRateLabel(new RateLabel(DialRateDuo)) { - // Widget setup goes top -> bottom level - // Top-level - this->setLayout(MajorOrganizer); + // Setup top-level layout this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - + this->setLayout(MajorOrganizer); + MajorOrganizer->setAlignment(Qt::AlignHCenter); + MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); - MajorOrganizer->setAlignment(Qt::AlignHCenter); - MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); + // Set dial-rate combo layout + DialRateDuo->setLayout(DuoOrganizer); + DuoOrganizer->addWidget(Dial, 0, 0); + DuoOrganizer->addWidget(NumericRateLabel, 0, 0); + DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter | Qt::AlignVCenter); + // Title this DialNameLabel->setText("Dial"); DialNameLabel->setScaledContents(true); DialNameLabel->setFont(DialNameFont); DialNameLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); DialNameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); - // Bottom-level - DialRateDuo->setLayout(DuoOrganizer); - - DuoOrganizer->addWidget(Dial, 0, 0); - DuoOrganizer->addWidget(NumericRateLabel, 0, 0); - + // Set how the dial-rate combo resizes QSizePolicy expandPolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter | Qt::AlignVCenter); DialRateDuo->setSizePolicy(expandPolicy); Dial->setSizePolicy(expandPolicy); -} +} // CompositeDial(QWidget* parent) CompositeDial::CompositeDial(const QString& title, QWidget* parent) : CompositeDial(parent) { From 0a5a113914117cbaf065b17a2bd900606d9f6aa3 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Wed, 1 Apr 2026 16:31:10 -0500 Subject: [PATCH 3/5] Reorganize qtysrates row --- .../Displays/QuantitiesRatesDisplay.cpp | 3 ++- src/Widgets/Displays/QuantitiesRatesRow.cpp | 20 +++++++++---------- src/Widgets/Displays/QuantitiesRatesRow.hpp | 7 ++++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp index 5010e96..625b5a2 100644 --- a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp +++ b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp @@ -3,7 +3,8 @@ namespace VSCL { -QtyRateDisplay::QtyRateDisplay(const QString& title, QWidget* parent) : QGroupBox(title, parent) { +QtyRateDisplay::QtyRateDisplay(const QString& title, QWidget* parent) + : QGroupBox(title, parent) { Organizer = new QVBoxLayout; Organizer->setContentsMargins(10, 10, 10, 10); setLayout(Organizer); diff --git a/src/Widgets/Displays/QuantitiesRatesRow.cpp b/src/Widgets/Displays/QuantitiesRatesRow.cpp index ffcb34e..19df44c 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.cpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.cpp @@ -2,23 +2,23 @@ #include "QuantitiesRatesDisplay.hpp" namespace VSCL { -QtyRateRow::QtyRateRow(const QString& title, QtyRateDisplay* parent) : QGroupBox(title, parent) { +QtyRateRow::QtyRateRow(const QString& title, QtyRateDisplay* parent) + : QGroupBox(title, parent) + , Title(title) + , Organizer(new QHBoxLayout(this)) + , QuantityLabel(new QLabel(this)) + , RateLabel(new QLabel(this)) { + parent->AddRow(this); - Title = title; + setLayout(Organizer); - Organizer = new QHBoxLayout; Organizer->setContentsMargins(5, 5, 5, 5); - setLayout(Organizer); + Organizer->addWidget(QuantityLabel); + Organizer->addWidget(RateLabel); - QuantityLabel = new QLabel(this); QuantityLabel->setText(QString::number(Quantity) + QuantityUnits); - Organizer->addWidget(QuantityLabel); - RateLabel = new QLabel(this); RateLabel->setText(QString::number(Rate) + RateUnits); - Organizer->addWidget(RateLabel); - TitleFont = QFont(); - LabelFont = QFont(); AdjustFontSize(); } diff --git a/src/Widgets/Displays/QuantitiesRatesRow.hpp b/src/Widgets/Displays/QuantitiesRatesRow.hpp index cca46d6..8010a04 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.hpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.hpp @@ -23,7 +23,6 @@ class QtyRateRow : public QGroupBox { void SetRateUnits(const QString& units); private: - QHBoxLayout* Organizer; double Quantity = 0.0; double Rate = 0.0; @@ -32,8 +31,10 @@ class QtyRateRow : public QGroupBox { QString RateUnits = tr("/s"); QString Title; - QFont TitleFont; - QFont LabelFont; + QFont TitleFont{ }; + QFont LabelFont{ }; + + QHBoxLayout* Organizer; QLabel* QuantityLabel; QLabel* RateLabel; From 4d77945f24f18a24fe7179621a3587c8bb96afc3 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Wed, 1 Apr 2026 17:11:51 -0500 Subject: [PATCH 4/5] Seldom-used windowing classes refactors and stop leaks --- CMakeLists.txt | 14 +++++++------- qml/circle.qml | 11 ----------- src/Windowing/DevWindow.cpp | 20 +++++++++++--------- src/Windowing/NumericTestWidget.cpp | 15 +++++++-------- 4 files changed, 25 insertions(+), 35 deletions(-) delete mode 100644 qml/circle.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index dd557f4..82f2cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,13 +18,13 @@ include("./cmake/qml.cmake") qt_standard_project_setup(REQUIRES 6.10) -#qt_add_executable(guidev WIN32 MACOSX_BUNDLE -# ${APP_SOURCES} ${WIDGET_SOURCES}) -# -#target_include_directories(guidev PRIVATE ${STD_APP_INCLUDES}) -#target_compile_warn_all(guidev) -# -#target_link_libraries(guidev PRIVATE ${STD_APP_QT6_DEPS}) +qt_add_executable(guidev WIN32 MACOSX_BUNDLE + ${APP_SOURCES} ${WIDGET_SOURCES}) + +target_include_directories(guidev PRIVATE ${STD_APP_INCLUDES}) +target_compile_warn_all(guidev) + +target_link_libraries(guidev PRIVATE ${STD_APP_QT6_DEPS}) # ## Ideally you would quickly iter on QML designs by using the dev gui app #qt_add_qml_module(qml.a_circle diff --git a/qml/circle.qml b/qml/circle.qml deleted file mode 100644 index a94ea71..0000000 --- a/qml/circle.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick - -Window { - visible: true - width: 360 - height: 240 - - Circle { - color: "#500000" - } -} diff --git a/src/Windowing/DevWindow.cpp b/src/Windowing/DevWindow.cpp index ba95777..669ec7a 100644 --- a/src/Windowing/DevWindow.cpp +++ b/src/Windowing/DevWindow.cpp @@ -6,20 +6,22 @@ #include "Dial/Attitude.hpp" namespace VSCL { -DevWindow::DevWindow() { - Stacker = new QStackedWidget; - setCentralWidget(Stacker); - - QLayout* layout = Stacker->layout(); - layout->setContentsMargins(5, 5, 5, 5); - - MainQuick = new QQuickWidget; - Stacker->addWidget(MainQuick); +DevWindow::DevWindow() + : QMainWindow() + , Stacker(new QStackedWidget(this)) + , MainQuick(new QQuickWidget(this)) + { AttitudeDial* dial = new AttitudeDial(this); NumericDisplaysTest = new NumericTestWidget(this, dial, [dial](int newValue) { dial->SetDialAngle(newValue); }); + + setCentralWidget(Stacker); + Stacker->addWidget(MainQuick); Stacker->addWidget(NumericDisplaysTest); + QLayout* layout = Stacker->layout(); + layout->setContentsMargins(5, 5, 5, 5); + CreateActions(); CreateMenus(); diff --git a/src/Windowing/NumericTestWidget.cpp b/src/Windowing/NumericTestWidget.cpp index e2a8e4c..aa2d810 100644 --- a/src/Windowing/NumericTestWidget.cpp +++ b/src/Windowing/NumericTestWidget.cpp @@ -6,27 +6,26 @@ namespace VSCL { NumericTestWidget::NumericTestWidget( QWidget* parent, QWidget* whatToTest, - std::function method) : QWidget(parent) { + std::function method) + : QWidget(parent) + , TesterSpinbox(new QDoubleSpinBox(this)) + , WidgetBeingTested(whatToTest) { - setParent(parent); - - QGridLayout* grid = new QGridLayout; + QGridLayout* grid = new QGridLayout(this); grid->setContentsMargins(25, 25, 25, 25); + grid->addWidget(TesterSpinbox, 0, 0); + grid->addWidget(WidgetBeingTested, 0, 1); setLayout(grid); - TesterSpinbox = new QDoubleSpinBox; TesterSpinbox->setRange(0.0, 360.0); TesterSpinbox->setSuffix("°"); TesterSpinbox->setWrapping(true); - grid->addWidget(TesterSpinbox, 0, 0); QSizePolicy sizePolicy; sizePolicy.setHorizontalPolicy(QSizePolicy::Expanding); sizePolicy.setVerticalPolicy(QSizePolicy::Expanding); - WidgetBeingTested = whatToTest; WidgetBeingTested->setSizePolicy(sizePolicy); - grid->addWidget(WidgetBeingTested, 0, 1); connect(TesterSpinbox, &QDoubleSpinBox::valueChanged, WidgetBeingTested, method); } // NumericTestWidget ctor From c41b986512e8ddffcac9bcf59b44eaa2cb8a6cf1 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Wed, 1 Apr 2026 17:20:17 -0500 Subject: [PATCH 5/5] Plug up more leaks from orphan QObject heap allocs --- CMakeLists.txt | 14 +++++++------- src/Plotting/Backend/CoreQChart.cpp | 1 + src/Plotting/Container.cpp | 2 +- src/Widgets/Displays/QuantitiesRatesDisplay.cpp | 4 ++-- src/Windowing/WidgetsRecreation.cpp | 17 +++++++---------- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82f2cca..dd557f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,13 +18,13 @@ include("./cmake/qml.cmake") qt_standard_project_setup(REQUIRES 6.10) -qt_add_executable(guidev WIN32 MACOSX_BUNDLE - ${APP_SOURCES} ${WIDGET_SOURCES}) - -target_include_directories(guidev PRIVATE ${STD_APP_INCLUDES}) -target_compile_warn_all(guidev) - -target_link_libraries(guidev PRIVATE ${STD_APP_QT6_DEPS}) +#qt_add_executable(guidev WIN32 MACOSX_BUNDLE +# ${APP_SOURCES} ${WIDGET_SOURCES}) +# +#target_include_directories(guidev PRIVATE ${STD_APP_INCLUDES}) +#target_compile_warn_all(guidev) +# +#target_link_libraries(guidev PRIVATE ${STD_APP_QT6_DEPS}) # ## Ideally you would quickly iter on QML designs by using the dev gui app #qt_add_qml_module(qml.a_circle diff --git a/src/Plotting/Backend/CoreQChart.cpp b/src/Plotting/Backend/CoreQChart.cpp index 33c7326..6b7dbef 100644 --- a/src/Plotting/Backend/CoreQChart.cpp +++ b/src/Plotting/Backend/CoreQChart.cpp @@ -6,6 +6,7 @@ namespace VSCL::Plot { PlotQChart::PlotQChart(QWidget* parent) : QChartView(parent) { SetWidgetRep(this); + // These heap allocs are parented when they get added to each other PlotChart = new QChart; LogTimeAxisQt = new QLogValueAxis; diff --git a/src/Plotting/Container.cpp b/src/Plotting/Container.cpp index 2e186db..6598ca7 100644 --- a/src/Plotting/Container.cpp +++ b/src/Plotting/Container.cpp @@ -5,7 +5,7 @@ namespace VSCL::Plot { PlotContainer::PlotContainer(QWidget* parent, EmbeddablePlot2D* newPlot) : QWidget(parent) { - QHBoxLayout* boxlay = new QHBoxLayout; + QHBoxLayout* boxlay = new QHBoxLayout(this); boxlay->setContentsMargins(5, 5, 5, 5); setLayout(boxlay); diff --git a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp index 625b5a2..888ebcb 100644 --- a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp +++ b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp @@ -4,8 +4,8 @@ namespace VSCL { QtyRateDisplay::QtyRateDisplay(const QString& title, QWidget* parent) - : QGroupBox(title, parent) { - Organizer = new QVBoxLayout; + : QGroupBox(title, parent) + , Organizer(new QVBoxLayout(this)) { Organizer->setContentsMargins(10, 10, 10, 10); setLayout(Organizer); }; diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 7ff1e2f..8061f75 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -47,7 +47,6 @@ Widgets::Widgets() { SetupTimeHistoryPlotQChart(); SetupAttQtysRatesDisplay(); SetupButtons(); - SetupStatusColumn(); SetGridColumnsMinimums(); SetGridRowsMinimums(); @@ -152,29 +151,29 @@ void Widgets::SetGridRowsMinimums() { // Buttons {{{ void Widgets::SetupButtons() { - LoadTestRoutineButton = new QPushButton; + LoadTestRoutineButton = new QPushButton(this); LoadTestRoutineButton->setText(tr("Load Test Routine")); - QuantityCalculatorButton = new QPushButton; + QuantityCalculatorButton = new QPushButton(this); QuantityCalculatorButton->setText(tr("Calculate Quantity")); - LogOpenButton = new QPushButton; + LogOpenButton = new QPushButton(this); LogOpenButton->setText(tr("Open Log")); - AbortButton = new QPushButton; + AbortButton = new QPushButton(this); AbortButton->setText(tr("Abort")); AbortButton->setStyleSheet(" QPushButton { background-color: red } "); } // void Widgets::SetupButtons() void Widgets::SetupStatusColumn() { - StatusColumn = new QGroupBox(tr("Operate")); + StatusColumn = new QGroupBox(tr("Operate"), this); MajorLayout->addWidget(StatusColumn, 1, 1); QSizePolicy vhexpanding; vhexpanding.setVerticalPolicy(QSizePolicy::MinimumExpanding); vhexpanding.setHorizontalPolicy(QSizePolicy::MinimumExpanding); - StatusColumnOrganizer = new QVBoxLayout; + StatusColumnOrganizer = new QVBoxLayout(StatusColumn); LoadTestRoutineButton->setSizePolicy(vhexpanding); StatusColumnOrganizer->addWidget(LoadTestRoutineButton); @@ -191,8 +190,6 @@ void Widgets::SetupStatusColumn() { } // void Widgets::SetupStatusColumn() void Widgets::SetAllButtonTextSize() { - // assumes equal button sizing in the layout (which is true as of March 16 2026) - // magic num: 30 pt when at orig and go from there ButtonFont.setPixelSize(ButtonFontAdjustment.AdjustPxSize(window())); LoadTestRoutineButton->setFont(ButtonFont); QuantityCalculatorButton->setFont(ButtonFont); @@ -218,7 +215,7 @@ void Widgets::SetupTimeHistoryPlotGR() { rollInfo.Color = Plot::RGBFromColorGR(Plot::ColorGR::Red); Plot::SeriesInfo pitchInfo; - pitchInfo.Name = "Pit.hpp"; + pitchInfo.Name = "Pitch"; pitchInfo.Color = Plot::RGBFromColorGR(Plot::ColorGR::Blue); Plot::SeriesInfo yawInfo;