From ce03d5bff5ca0c06ac884628c8ef65b902de669f Mon Sep 17 00:00:00 2001 From: Nikita Kostovsky Date: Sat, 9 Nov 2024 17:28:58 +0100 Subject: Initial commit --- Main.qml | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 Main.qml (limited to 'Main.qml') diff --git a/Main.qml b/Main.qml new file mode 100644 index 0000000..a5415c2 --- /dev/null +++ b/Main.qml @@ -0,0 +1,307 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QmlCustomPlot 1.0 + +import "request.js" as XHR + +ApplicationWindow { + id: mainWindowRoot + + width: 640 + height: 480 + visible: true + // visibility: Window.Maximized + visibility: ApplicationWindow.Maximized + + title: qsTr("Hello World") + + // // pistache + // // readonly property string apiRoot: "http://rpi5:8080/v1" + // // qhttpserver + readonly property string apiRoot: "http://rpi5:8081/v1" + + Shortcut { + sequence: "ctrl+q" + onActivated: mainWindowRoot.close() + } + + Material.theme: Material.Dark + Material.accent: Material.Indigo + + function requestExposureTime(type, uri) { + console.log("request url: ", apiRoot + uri); + + XHR.sendRequest("GET", apiRoot + uri, function(response) { + + if (response.status != "200") { + console.log("response status: ", response.status); + return; + } + + let isPlainText = response.contentType.length === 0 + + if (!isPlainText) { + console.log("invalid response: ", response); + return; + } + + exposureTimeSpinBox.value = parseInt(response.content) + }); + } + + function readParams() { + var url = apiRoot + "/sensor/params" + console.log("readParams:", url); + + XHR.sendRequest("GET", url, function(response) { + + if (response.status != "200") { + console.log("response status: ", response.status); + return; + } + + let isPlainText = response.contentType.length === 0 + + if (!isPlainText) { + console.log("invalid response: ", response); + return; + } + + var json = JSON.parse(response.content); + + console.log("readParams result:", json) + + if (exposureTimeSpinBox.value != json.exposureTime) { + console.log("update exposureTimeSpinBox to", json.exposureTime) + exposureTimeSpinBox.value = json.exposureTime; + } + + if (laserLevelSpinBox.value != json.laserLevel) { + console.log("update laserLevelSpinBox to", json.laserLevel) + laserLevelSpinBox.value = json.laserLevel; + } + + if (enableAutoExposureCheckbox.checked != (json.aeEnable == "true")) { + console.log("update enableAutoExposureCheckbox to", json.aeEnable) + enableAutoExposureCheckbox.checked = json.aeEnable == "true"; + } + }); + } + + Component.onCompleted: readParams() + + function writeParams() { + var url = apiRoot + "/sensor/params"; + console.log("writeParams:", url); + + var json = new Object(); + json["aeEnable"] = enableAutoExposureCheckbox.checked; + json["exposureTime"] = exposureTimeSpinBox.value; + json["laserLevel"] = laserLevelSpinBox.value; + console.log(JSON.stringify(json)); + + XHR.sendRequest("POST", url, function(response) { + + if (response.status != "200") { + console.log("response status: ", response.status); + return; + } + + let isPlainText = response.contentType.length === 0; + + if (!isPlainText) { + console.log("invalid response: ", response); + return; + } + + console.log("writeParams result:", response.content); + + // var json = JSON.parse(response.content); + }, JSON.stringify(json)); + } + + RowLayout { + id: horizontalLayout + + anchors.fill: parent + + spacing: 0 + + Pane { + id: pane + + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: 150 + + ColumnLayout { + id: columnLayout + + anchors.fill: parent + + function color_by_value(value) { + const limit = 0.02; + + if (value >= limit) { + return "red"; + } + + return "green"; + } + + Label { + id: fpsLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + color: "green" + } + + Label { + id: maxDiffLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + color: columnLayout.color_by_value(max_diff) + text: "max diff: " + max_diff.toFixed(3) + } + + Label { + id: maxDiffIdxLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + text: "max diff: " + max_diff_idx + } + + Label { + id: minDiffLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + color: columnLayout.color_by_value(-min_diff) + text: "min diff: " + min_diff.toFixed(3) + } + + Label { + id: minDiffIdxLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + text: "min diff: " + min_diff_idx + } + + Label { + id: avgDiffLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + color: columnLayout.color_by_value(avg_diff) + text: "avg diff: " + avg_diff.toFixed(3) + } + + Label { + id: medianhDiffLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + color: columnLayout.color_by_value(median_diff) + text: "med. diff: " + median_diff.toFixed(3) + } + + Label { + text: qsTr("Exposure time (us):") + } + + SpinBox { + id: exposureTimeSpinBox + + Layout.fillWidth: true + + from: 10 + to: 30000 + stepSize: 100 + editable: true + + value: 200 + onValueChanged: writeParams() + } + + SpinBox { + id: laserLevelSpinBox + + Layout.fillWidth: true + + from: 500 + to: 30000 + stepSize: 250 + editable: true + + value: 1500 + onValueChanged: writeParams() + } + + CheckBox { + id: enableAutoExposureCheckbox + + text: qsTr("Auto exposure") + + onCheckedChanged: writeParams() + } + + Item { + Layout.fillHeight: true + } + } + } + + ImageViewer { + id: image + + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: 200 + } + + Item { + + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: 900 + Layout.minimumHeight: 600 + + Rectangle { + color: "red" + opacity: 0.1 + z: 101 + } + + QmlCustomPlot { + id: qmlPlot + + anchors.fill: parent + + Label { + anchors { + top: parent.top + topMargin: 8 * 2 + horizontalCenter: parent.horizontalCenter + } + text: qmlPlot.fps + } + + plot: myPlot + // Component.onCompleted: initCustomPlot() + } + } + } +} -- cgit v1.2.3-70-g09d2