Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate GUI to Qt6 #1330

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "software/gui/src/third_party/qnanopainter"]
path = software/gui/src/third_party/qnanopainter
url = https://github.com/QUItCoding/qnanopainter
10 changes: 5 additions & 5 deletions software/gui/app/AlarmSound.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ SoundEffect {

function update() {
switch(root.priority) {
case AlarmPriority.HIGH: source = 'qrc:/sounds/alarm_high.wav'; break;
case AlarmPriority.MEDIUM: source = 'qrc:/sounds/alarm_medium.wav'; break;
case tAlarmPriority.HIGH: source = 'qrc:/sounds/alarm_high.wav'; break;
case tAlarmPriority.MEDIUM: source = 'qrc:/sounds/alarm_medium.wav'; break;
// TODO: Currently we don't have any low priority alarms, but this needs
// a tone similar to alarm_medium.wav but with only two beeps.
case AlarmPriority.LOW: source = ''; break;
case AlarmPriority.NONE: source = ''; break;
case tAlarmPriority.LOW: source = ''; break;
case tAlarmPriority.NONE: source = ''; break;
}

if(priority != AlarmPriority.NONE) {
if(priority != tAlarmPriority.NONE) {
play()
} else {
stop()
Expand Down
8 changes: 4 additions & 4 deletions software/gui/app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
set(this_target ${PROJECT_NAME}_app)

find_package(Qt5 COMPONENTS Qml REQUIRED)
find_package(Qt6 COMPONENTS Qml REQUIRED)

message(STATUS "Using QtCore v. ${Qt5Qml_VERSION_STRING}")
message(STATUS "Using QtCore v. ${Qt6Qml_VERSION_STRING}")

set(${this_target}_sources
main.cpp
Expand All @@ -11,7 +11,7 @@ set(${this_target}_sources
#set(${this_target}_headers
# )

qt5_add_resources(${this_target}_resources
qt6_add_resources(${this_target}_resources
qml.qrc
controls/controls.qrc
fonts/fonts.qrc
Expand Down Expand Up @@ -39,7 +39,7 @@ target_include_directories(
target_link_libraries(
${this_target}
${PROJECT_NAME}_backend
Qt5::Qml
Qt6::Qml
)

#DISTFILES += images/Logo.png \
Expand Down
18 changes: 9 additions & 9 deletions software/gui/app/Style.qml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ QtObject {
property var parameterBackgroundByPriority: function(p) {
var c = Style.theme.color
switch (p) {
case AlarmPriority.HIGH: return c.alarmHighBright;
case AlarmPriority.MEDIUM: return c.alarmMediumBright;
case AlarmPriority.LOW: return c.alarmLowBright;
case tAlarmPriority.HIGH: return c.alarmHighBright;
case tAlarmPriority.MEDIUM: return c.alarmMediumBright;
case tAlarmPriority.LOW: return c.alarmLowBright;
default: return "transparent";
}
}
Expand All @@ -70,18 +70,18 @@ QtObject {
property var lineByPriority: function(p) {
var c = Style.theme.color
switch (p) {
case AlarmPriority.HIGH: return c.alarmHighBright;
case AlarmPriority.MEDIUM: return c.alarmMediumBright;
case AlarmPriority.LOW: return c.alarmLowBright;
case tAlarmPriority.HIGH: return c.alarmHighBright;
case tAlarmPriority.MEDIUM: return c.alarmMediumBright;
case tAlarmPriority.LOW: return c.alarmLowBright;
default: return c.normalGraphLine;
}
}
property var areaByPriority: function(p) {
var c = Style.theme.color
switch (p) {
case AlarmPriority.HIGH: return c.alarmHighDim;
case AlarmPriority.MEDIUM: return c.alarmMediumDim;
case AlarmPriority.LOW: return c.alarmLowDim;
case tAlarmPriority.HIGH: return c.alarmHighDim;
case tAlarmPriority.MEDIUM: return c.alarmMediumDim;
case tAlarmPriority.LOW: return c.alarmLowDim;
default: return c.normalGraphArea;
}
}
Expand Down
12 changes: 6 additions & 6 deletions software/gui/app/controls/AlarmButton.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ HeaderButton {

property int numAlarms: 0
property int remainingSilenceMs: 0
property int priority: AlarmPriority.NONE
property int priority: tAlarmPriority.NONE

property color alarm_button_fg: "white"

width: remainingSilenceText.visible ? 168 : 104;
height: 40

state: switch(priority) {
case AlarmPriority.NONE: ""; break;
case AlarmPriority.LOW: "low"; break;
case AlarmPriority.MEDIUM: "medium"; break;
case AlarmPriority.HIGH: "high"; break;
case tAlarmPriority.NONE: ""; break;
case tAlarmPriority.LOW: "low"; break;
case tAlarmPriority.MEDIUM: "medium"; break;
case tAlarmPriority.HIGH: "high"; break;
}


Expand Down Expand Up @@ -78,7 +78,7 @@ HeaderButton {
width: 20; height: 20
sourceSize: Qt.size(width, height)
fillMode: Image.PreserveAspectFit
source: root.priority != AlarmPriority.NONE ?
source: root.priority != tAlarmPriority.NONE ?
'qrc:/images/RW_alarm-off_24.svg' :
'qrc:/images/RW_alarm_24.svg'
layer.enabled: true
Expand Down
12 changes: 6 additions & 6 deletions software/gui/app/controls/AlarmNotificationBanner.qml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ Item {

property alias title: titleText.text
property int numActiveAlarms: 0
property int priority: AlarmPriority.NONE
property int priority: tAlarmPriority.NONE

enabled: priority != AlarmPriority.NONE
enabled: priority != tAlarmPriority.NONE

signal pauseAlarmClicked()

state: switch(priority) {
case AlarmPriority.NONE: ""; break;
case AlarmPriority.LOW: "low"; break;
case AlarmPriority.MEDIUM: "medium"; break;
case AlarmPriority.HIGH: "high"; break;
case tAlarmPriority.NONE: ""; break;
case tAlarmPriority.LOW: "low"; break;
case tAlarmPriority.MEDIUM: "medium"; break;
case tAlarmPriority.HIGH: "high"; break;
}


Expand Down
2 changes: 1 addition & 1 deletion software/gui/app/controls/MainHeader.qml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Control {
}
priority: {
var alarm = GuiStateContainer.alarmManager.highestPrioritySilencedAlarm
return (alarm == null) ? AlarmPriority.NONE : alarm.nominalPriority
return (alarm == null) ? tAlarmPriority.NONE : alarm.nominalPriority
}
numAlarms: GuiStateContainer.alarmManager.numSilencedAlarms
remainingSilenceMs: {
Expand Down
2 changes: 1 addition & 1 deletion software/gui/app/controls/ParameterDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Rectangle {
antialiasing: true
radius: 8

property int alarmPriority: AlarmPriority.NONE
property int tAlarmPriority: tAlarmPriority.NONE

// define parameter name, e.g. PIP
property alias parameterName: parameterNameText.text
Expand Down
2 changes: 1 addition & 1 deletion software/gui/app/controls/ScopeView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Item {
property double yMin: -1.5
property double yMax: 1.5
property double rangeInSeconds: 30
property int alarmPriority: AlarmPriority.NONE
property int tAlarmPriority: tAlarmPriority.NONE

property alias name: nameLabel.text
property alias unit: unitLabel.text
Expand Down
2 changes: 1 addition & 1 deletion software/gui/app/controls/graphs/PressureGraph.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ScopeView {
yMin: 0
yMax: 60

alarmPriority: Math.max(
tAlarmPriority: Math.max(
GuiStateContainer.alarmManager.pipExceededAlarm.effectiveVisualPriority,
GuiStateContainer.alarmManager.pipNotReachedAlarm.effectiveVisualPriority)
}
2 changes: 1 addition & 1 deletion software/gui/app/controls/readings/PipDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ParameterDisplay {
parameterName: qsTr("PIP")
parameterUnit: qsTr("cmH<sub>2</sub>O")
parameterValue: GuiStateContainer.measured_pip.toString()
alarmPriority: Math.max(
tAlarmPriority: Math.max(
GuiStateContainer.alarmManager.pipExceededAlarm.effectiveVisualPriority,
GuiStateContainer.alarmManager.pipNotReachedAlarm.effectiveVisualPriority)
}
64 changes: 28 additions & 36 deletions software/gui/app/main.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
#include "chrono.h"
#include "connected_device.h"
#include "controller_history.h"
#include "gui_state_container.h"
#include "latching_alarm.h"
#include "periodic_closure.h"
#include "respira_connected_device.h"

#include "logger.h"
#include <QStandardPaths>

#include "time_series_graph.h"
#include <QCommandLineParser>
#include <QDebug>
#include <QFontDatabase>
#include <QFontInfo>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QStandardPaths>
#include <QtCore/QDir>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
Expand All @@ -24,6 +13,16 @@
#include <iostream>
#include <memory>

#include "chrono.h"
#include "connected_device.h"
#include "controller_history.h"
#include "gui_state_container.h"
#include "latching_alarm.h"
#include "logger.h"
#include "periodic_closure.h"
#include "respira_connected_device.h"
#include "time_series_graph.h"

QObject *gui_state_instance(QQmlEngine *engine, QJSEngine *scriptEngine) {
static GuiStateContainer state_container(
/*history_window=*/DurationMs(30000),
Expand All @@ -50,17 +49,14 @@ void install_fonts() {
}

void init_logger(bool debug_mode) {
auto log_path =
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
auto log_path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
QDir().mkpath(log_path);
auto log_file = log_path + "/gui.log";
printf("Saving logs in %s\n", log_file.toLatin1().data());
if (debug_mode) {
CustomLogger::initLogger(spdlog::level::trace, true,
log_file.toStdString());
CustomLogger::initLogger(spdlog::level::trace, true, log_file.toStdString());
} else {
CustomLogger::initLogger(spdlog::level::info, false,
log_file.toStdString());
CustomLogger::initLogger(spdlog::level::info, false, log_file.toStdString());
}
}

Expand Down Expand Up @@ -90,10 +86,10 @@ int main(int argc, char *argv[]) {
QStringList() << "startup-only",
QObject::tr("main", "Start up and exit successfully (for testing)"));

QCommandLineOption serialPortOption(
QStringList() << "serial-port",
QObject::tr("main", "Serial port filename. "
"Uses pre-recorded test data if not set."));
QCommandLineOption serialPortOption(QStringList() << "serial-port",
QObject::tr("main",
"Serial port filename. "
"Uses pre-recorded test data if not set."));
serialPortOption.setValueName("port");

parser.addOption(startupOnlyOption);
Expand All @@ -109,8 +105,7 @@ int main(int argc, char *argv[]) {
std::unique_ptr<ConnectedDevice> device;
if (parser.isSet(serialPortOption)) {
state_container->set_is_using_fake_data(false);
device = std::make_unique<RespiraConnectedDevice>(
parser.value(serialPortOption));
device = std::make_unique<RespiraConnectedDevice>(parser.value(serialPortOption));
} else {
state_container->set_is_using_fake_data(true);
// NOTE: The code below is specialized to this particular file.
Expand All @@ -123,8 +118,7 @@ int main(int argc, char *argv[]) {
while (!file.atEnd()) {
QString line{file.readLine()};
line = line.trimmed();
if (line.isEmpty() || line.startsWith("#") || line.startsWith("time"))
continue;
if (line.isEmpty() || line.startsWith("#") || line.startsWith("time")) continue;
auto tokens = line.split(" ").toVector();

ControllerStatus status = ControllerStatus_init_zero;
Expand Down Expand Up @@ -175,16 +169,14 @@ int main(int argc, char *argv[]) {
communicate.Start();

qmlRegisterType<TimeSeriesGraph>("Respira", 1, 0, "TimeSeriesGraph");
qmlRegisterUncreatableType<AlarmPriority>("Respira", 1, 0, "AlarmPriority",
"is an enum");
qmlRegisterUncreatableType<AlarmManager>(
"Respira", 1, 0, "AlarmManager",
"AlarmManager cannot be instantiated from QML");
qmlRegisterUncreatableType<LatchingAlarm>(
"Respira", 1, 0, "LatchingAlarm",
"LatchingAlarm cannot be instantiated from QML");
qmlRegisterSingletonType<GuiStateContainer>(
"Respira", 1, 0, "GuiStateContainer", &gui_state_instance);
qmlRegisterUncreatableType<AlarmPriority>("Respira", 1, 0, "tAlarmPriority",
"AlarmPriority cannot be instantiated from QML");
qmlRegisterUncreatableType<AlarmManager>("Respira", 1, 0, "AlarmManager",
"AlarmManager cannot be instantiated from QML");
qmlRegisterUncreatableType<LatchingAlarm>("Respira", 1, 0, "LatchingAlarm",
"LatchingAlarm cannot be instantiated from QML");
qmlRegisterSingletonType<GuiStateContainer>("Respira", 1, 0, "GuiStateContainer",
&gui_state_instance);

install_fonts();

Expand Down
2 changes: 1 addition & 1 deletion software/gui/app/main.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import QtQuick 2.11
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.4
import QtQuick.Controls 2.12
import Respira 1.0
import "modes"
import "controls"
Expand Down
1 change: 1 addition & 0 deletions software/gui/conanfile.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[requires]
fmt/9.1.0
spdlog/1.11.0
qt/6.4.2

[generators]
cmake
Expand Down
Loading