arrheniuscalculator 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arrheniuscalculator-0.1.1/LICENSE +21 -0
- arrheniuscalculator-0.1.1/PKG-INFO +56 -0
- arrheniuscalculator-0.1.1/README.md +46 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/__init__.py +0 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/main.py +26 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/AboutView.qml +128 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/AppButton.qml +63 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/ArrheniusCalculator/Style.qml +12 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/ArrheniusCalculator/qmldir +2 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/BasicCalculationView.qml +512 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/HomeView.qml +126 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/Main.qml +38 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator/qml/OptionView.qml +108 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/PKG-INFO +56 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/SOURCES.txt +19 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/dependency_links.txt +1 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/entry_points.txt +2 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/requires.txt +1 -0
- arrheniuscalculator-0.1.1/arrheniuscalculator.egg-info/top_level.txt +1 -0
- arrheniuscalculator-0.1.1/pyproject.toml +26 -0
- arrheniuscalculator-0.1.1/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tilen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: arrheniuscalculator
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A simple GUI tool for calculating Arrhenius integral.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: pyside6
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
|
|
11
|
+
# ArrheniusCalculator
|
|
12
|
+
|
|
13
|
+
The intention of this project is to develop a simple QML GUI application that will calculate the Arrhenius integral for various cases (tabular data, functional data, etc.).
|
|
14
|
+
|
|
15
|
+
The project is currently in the process of being published on pypi package index, so except installation instructions to not work correctly.
|
|
16
|
+
|
|
17
|
+
## Option 1: Install from PyPi
|
|
18
|
+
|
|
19
|
+
### Option a: Using uv
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add arrheniuscalculator
|
|
23
|
+
uv run arrheniuscalculator
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Option b: Using pip
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install arrheniuscalculator
|
|
30
|
+
arrheniuscalculator
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Option 2: Installation from source
|
|
34
|
+
|
|
35
|
+
### Option a: Using uv
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
39
|
+
cd ArrheniusCalculator
|
|
40
|
+
uv sync
|
|
41
|
+
uv run python -m arrheniuscalculator.main
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option b: Using pip
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
48
|
+
cd ArrheniusCalculator
|
|
49
|
+
|
|
50
|
+
python -m venv .venv
|
|
51
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
52
|
+
|
|
53
|
+
pip install -e .
|
|
54
|
+
python -m arrheniuscalculator.main
|
|
55
|
+
```
|
|
56
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ArrheniusCalculator
|
|
2
|
+
|
|
3
|
+
The intention of this project is to develop a simple QML GUI application that will calculate the Arrhenius integral for various cases (tabular data, functional data, etc.).
|
|
4
|
+
|
|
5
|
+
The project is currently in the process of being published on pypi package index, so except installation instructions to not work correctly.
|
|
6
|
+
|
|
7
|
+
## Option 1: Install from PyPi
|
|
8
|
+
|
|
9
|
+
### Option a: Using uv
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv add arrheniuscalculator
|
|
13
|
+
uv run arrheniuscalculator
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Option b: Using pip
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install arrheniuscalculator
|
|
20
|
+
arrheniuscalculator
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Option 2: Installation from source
|
|
24
|
+
|
|
25
|
+
### Option a: Using uv
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
29
|
+
cd ArrheniusCalculator
|
|
30
|
+
uv sync
|
|
31
|
+
uv run python -m arrheniuscalculator.main
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Option b: Using pip
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
38
|
+
cd ArrheniusCalculator
|
|
39
|
+
|
|
40
|
+
python -m venv .venv
|
|
41
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
42
|
+
|
|
43
|
+
pip install -e .
|
|
44
|
+
python -m arrheniuscalculator.main
|
|
45
|
+
```
|
|
46
|
+
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from PySide6.QtGui import QGuiApplication
|
|
5
|
+
from PySide6.QtQml import QQmlApplicationEngine
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
app = QGuiApplication(sys.argv)
|
|
10
|
+
app.setApplicationName("Arrhenius Calculator")
|
|
11
|
+
app.setOrganizationName("ArrheniusCalc")
|
|
12
|
+
|
|
13
|
+
engine = QQmlApplicationEngine()
|
|
14
|
+
|
|
15
|
+
qml_dir = Path(__file__).parent / "qml"
|
|
16
|
+
engine.addImportPath(str(qml_dir)) # points at qml/, which contains ArrheniusCalculator/
|
|
17
|
+
engine.load(qml_dir / "Main.qml")
|
|
18
|
+
|
|
19
|
+
if not engine.rootObjects():
|
|
20
|
+
sys.exit(-1)
|
|
21
|
+
|
|
22
|
+
sys.exit(app.exec())
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
main()
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import QtQuick.Layouts
|
|
4
|
+
import ArrheniusCalculator
|
|
5
|
+
|
|
6
|
+
// ── About view ────────────────────────────────────────────────────────────
|
|
7
|
+
Item {
|
|
8
|
+
id: root
|
|
9
|
+
|
|
10
|
+
// Grab the StackView from the parent hierarchy
|
|
11
|
+
property StackView stackView: StackView.view as StackView
|
|
12
|
+
|
|
13
|
+
ColumnLayout {
|
|
14
|
+
anchors {
|
|
15
|
+
fill: parent
|
|
16
|
+
margins: 36
|
|
17
|
+
}
|
|
18
|
+
spacing: 24
|
|
19
|
+
|
|
20
|
+
// ── Header row: back button + title ───────────────────────────────
|
|
21
|
+
RowLayout {
|
|
22
|
+
Layout.fillWidth: true
|
|
23
|
+
spacing: 12
|
|
24
|
+
|
|
25
|
+
// Back button (icon-style arrow)
|
|
26
|
+
Rectangle {
|
|
27
|
+
id: backBtn
|
|
28
|
+
implicitWidth: 36
|
|
29
|
+
implicitHeight: 36
|
|
30
|
+
radius: 18
|
|
31
|
+
color: backMouse.containsMouse
|
|
32
|
+
? Style.colorAccent
|
|
33
|
+
: "transparent"
|
|
34
|
+
border.color: Style.colorAccent
|
|
35
|
+
border.width: 1.5
|
|
36
|
+
|
|
37
|
+
Behavior on color {
|
|
38
|
+
ColorAnimation { duration: 120 }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Text {
|
|
42
|
+
anchors.centerIn: parent
|
|
43
|
+
text: "←"
|
|
44
|
+
font.pixelSize: 16
|
|
45
|
+
color: backMouse.containsMouse
|
|
46
|
+
? Style.colorSurface
|
|
47
|
+
: Style.colorAccent
|
|
48
|
+
|
|
49
|
+
Behavior on color {
|
|
50
|
+
ColorAnimation { duration: 120 }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
MouseArea {
|
|
55
|
+
id: backMouse
|
|
56
|
+
anchors.fill: parent
|
|
57
|
+
hoverEnabled: true
|
|
58
|
+
cursorShape: Qt.PointingHandCursor
|
|
59
|
+
onClicked: root.stackView.pop()
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Text {
|
|
64
|
+
Layout.fillWidth: true
|
|
65
|
+
text: qsTr("About")
|
|
66
|
+
font {
|
|
67
|
+
family: "Georgia"
|
|
68
|
+
pixelSize: 26
|
|
69
|
+
weight: Font.DemiBold
|
|
70
|
+
letterSpacing: 0.5
|
|
71
|
+
}
|
|
72
|
+
color: Style.colorText
|
|
73
|
+
horizontalAlignment: Text.AlignLeft
|
|
74
|
+
verticalAlignment: Text.AlignVCenter
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Thin accent rule
|
|
79
|
+
Rectangle {
|
|
80
|
+
Layout.fillWidth: true
|
|
81
|
+
Layout.preferredHeight: 2
|
|
82
|
+
color: Style.colorAccent
|
|
83
|
+
opacity: 0.25
|
|
84
|
+
radius: 1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ── Content card ──────────────────────────────────────────────────
|
|
88
|
+
Rectangle {
|
|
89
|
+
Layout.fillWidth: true
|
|
90
|
+
Layout.fillHeight: true
|
|
91
|
+
color: Style.colorSurface
|
|
92
|
+
border.color: Style.colorBorder
|
|
93
|
+
border.width: 1
|
|
94
|
+
radius: 8
|
|
95
|
+
|
|
96
|
+
ScrollView {
|
|
97
|
+
anchors {
|
|
98
|
+
fill: parent
|
|
99
|
+
margins: 24
|
|
100
|
+
}
|
|
101
|
+
clip: true
|
|
102
|
+
contentWidth: availableWidth
|
|
103
|
+
|
|
104
|
+
Text {
|
|
105
|
+
width: parent.width
|
|
106
|
+
text: qsTr(
|
|
107
|
+
"Arrhenius Calculator\n\n" +
|
|
108
|
+
"Version: 0.1.1 (pre-release)\n\n" +
|
|
109
|
+
"About & instructions — yet to be added.\n\n" +
|
|
110
|
+
"This section will describe the purpose of the tool, " +
|
|
111
|
+
"the Arrhenius equation background, how to enter data, " +
|
|
112
|
+
"and how to interpret results."
|
|
113
|
+
)
|
|
114
|
+
font {
|
|
115
|
+
family: "Georgia"
|
|
116
|
+
pixelSize: 14
|
|
117
|
+
}
|
|
118
|
+
color: Style.colorText
|
|
119
|
+
lineHeight: 1.6
|
|
120
|
+
wrapMode: Text.WordWrap
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Small bottom padding
|
|
126
|
+
Item { Layout.preferredHeight: 4 }
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import ArrheniusCalculator
|
|
4
|
+
|
|
5
|
+
// ── Reusable button ───────────────────────────────────────────────────────
|
|
6
|
+
// Usage:
|
|
7
|
+
// AppButton { text: "Launch"; primary: true; onClicked: { … } }
|
|
8
|
+
// AppButton { text: "About"; primary: false; onClicked: { … } }
|
|
9
|
+
AbstractButton {
|
|
10
|
+
id: control
|
|
11
|
+
|
|
12
|
+
// true → filled accent button
|
|
13
|
+
// false → outlined secondary button
|
|
14
|
+
property bool primary: true
|
|
15
|
+
|
|
16
|
+
implicitHeight: 42
|
|
17
|
+
implicitWidth: 120
|
|
18
|
+
|
|
19
|
+
hoverEnabled: true
|
|
20
|
+
HoverHandler { cursorShape: Qt.PointingHandCursor }
|
|
21
|
+
|
|
22
|
+
// ── Visuals ───────────────────────────────────────────────────────────
|
|
23
|
+
background: Rectangle {
|
|
24
|
+
radius: 6
|
|
25
|
+
color: {
|
|
26
|
+
if (control.primary) {
|
|
27
|
+
return control.hovered
|
|
28
|
+
? Style.colorAccentHov
|
|
29
|
+
: Style.colorAccent
|
|
30
|
+
}
|
|
31
|
+
return control.hovered
|
|
32
|
+
? Qt.rgba(0.17, 0.29, 0.49, 0.08) // very light tint on hover
|
|
33
|
+
: "transparent"
|
|
34
|
+
}
|
|
35
|
+
border.color: Style.colorAccent
|
|
36
|
+
border.width: 1.5
|
|
37
|
+
|
|
38
|
+
Behavior on color {
|
|
39
|
+
ColorAnimation { duration: 130 }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
contentItem: Text {
|
|
44
|
+
text: control.text
|
|
45
|
+
font {
|
|
46
|
+
family: "Georgia"
|
|
47
|
+
pixelSize: 14
|
|
48
|
+
weight: Font.Medium
|
|
49
|
+
letterSpacing: 0.3
|
|
50
|
+
}
|
|
51
|
+
color: control.primary
|
|
52
|
+
? Style.colorSurface
|
|
53
|
+
: Style.colorAccent
|
|
54
|
+
horizontalAlignment: Text.AlignHCenter
|
|
55
|
+
verticalAlignment: Text.AlignVCenter
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Scale micro-interaction on press
|
|
59
|
+
scale: control.pressed ? 0.97 : 1.0
|
|
60
|
+
Behavior on scale {
|
|
61
|
+
NumberAnimation { duration: 80 }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
pragma Singleton
|
|
2
|
+
import QtQuick
|
|
3
|
+
|
|
4
|
+
QtObject {
|
|
5
|
+
readonly property color colorBg: "#F5F2EC"
|
|
6
|
+
readonly property color colorSurface: "#FFFFFF"
|
|
7
|
+
readonly property color colorBorder: "#D6CFC4"
|
|
8
|
+
readonly property color colorAccent: "#2C4A7C"
|
|
9
|
+
readonly property color colorAccentHov: "#1E3560"
|
|
10
|
+
readonly property color colorText: "#1A1A2E"
|
|
11
|
+
readonly property color colorMuted: "#7A7A8C"
|
|
12
|
+
}
|
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import QtQuick.Layouts
|
|
4
|
+
import ArrheniusCalculator
|
|
5
|
+
|
|
6
|
+
// ── Basic Arrhenius calculation view ─────────────────────────────────────
|
|
7
|
+
// Formula: Ω = A · exp(−Ea / (R · T)) · Δt
|
|
8
|
+
// VHS: (1/Ω_vhs)^p = (1/Ω₁)^p + (1/Ω₂)^p
|
|
9
|
+
Item {
|
|
10
|
+
id: root
|
|
11
|
+
|
|
12
|
+
property StackView stackView: StackView.view as StackView
|
|
13
|
+
|
|
14
|
+
// ── Fix 1: enlarge the ApplicationWindow when this view is pushed ─────
|
|
15
|
+
Component.onCompleted: {
|
|
16
|
+
var w = Window.window
|
|
17
|
+
if (w) {
|
|
18
|
+
if (w.width < 600) w.width = 600
|
|
19
|
+
if (w.height < 870) w.height = 870
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ── Constants ─────────────────────────────────────────────────────────
|
|
24
|
+
readonly property real gasConstant: 8.314462618 // J/(mol·K)
|
|
25
|
+
|
|
26
|
+
// ── Helpers ───────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
// Fix 2: evaluate simple arithmetic before converting to float.
|
|
29
|
+
// Supports +, -, *, / and scientific notation (45+273.15, 6.2e88 …).
|
|
30
|
+
function parseVal(text) {
|
|
31
|
+
var s = text.trim()
|
|
32
|
+
if (s === "") return 0.0
|
|
33
|
+
try {
|
|
34
|
+
// Function constructor evaluates a JS expression safely from
|
|
35
|
+
// user-supplied text (no external injection; same trust level as
|
|
36
|
+
// the rest of the QML user-input fields).
|
|
37
|
+
var result = Function('"use strict"; return (' + s + ')')()
|
|
38
|
+
var v = Number(result)
|
|
39
|
+
return isFinite(v) ? v : 0.0
|
|
40
|
+
} catch (e) {
|
|
41
|
+
var v2 = parseFloat(s)
|
|
42
|
+
return isNaN(v2) ? 0.0 : v2
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function calcOmega(A, Ea, T, dt) {
|
|
47
|
+
if (T <= 0) return NaN
|
|
48
|
+
return A * Math.exp(-Ea / (gasConstant * T)) * dt
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function formatResult(val) {
|
|
52
|
+
if (isNaN(val) || !isFinite(val)) return "—"
|
|
53
|
+
if (Math.abs(val) >= 1e6 || (Math.abs(val) < 1e-3 && val !== 0))
|
|
54
|
+
return val.toExponential(4)
|
|
55
|
+
return val.toPrecision(6)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ── State ─────────────────────────────────────────────────────────────
|
|
59
|
+
property real omega1: NaN
|
|
60
|
+
property real omega2: NaN
|
|
61
|
+
property real omegaVHS: NaN
|
|
62
|
+
|
|
63
|
+
// ── Scroll wrapper ────────────────────────────────────────────────────
|
|
64
|
+
ScrollView {
|
|
65
|
+
anchors.fill: parent
|
|
66
|
+
contentWidth: availableWidth
|
|
67
|
+
clip: true
|
|
68
|
+
|
|
69
|
+
ColumnLayout {
|
|
70
|
+
width: parent.width
|
|
71
|
+
anchors {
|
|
72
|
+
left: parent.left
|
|
73
|
+
right: parent.right
|
|
74
|
+
margins: 32
|
|
75
|
+
}
|
|
76
|
+
spacing: 0
|
|
77
|
+
|
|
78
|
+
// ── Header ────────────────────────────────────────────────────
|
|
79
|
+
Item { Layout.preferredHeight: 28 }
|
|
80
|
+
|
|
81
|
+
RowLayout {
|
|
82
|
+
Layout.fillWidth: true
|
|
83
|
+
spacing: 12
|
|
84
|
+
|
|
85
|
+
Rectangle {
|
|
86
|
+
id: backBtn
|
|
87
|
+
implicitWidth: 36
|
|
88
|
+
implicitHeight: 36
|
|
89
|
+
radius: 18
|
|
90
|
+
color: backMouse.containsMouse ? Style.colorAccent : "transparent"
|
|
91
|
+
border.color: Style.colorAccent
|
|
92
|
+
border.width: 1.5
|
|
93
|
+
Behavior on color { ColorAnimation { duration: 120 } }
|
|
94
|
+
|
|
95
|
+
Text {
|
|
96
|
+
anchors.centerIn: parent
|
|
97
|
+
text: "←"
|
|
98
|
+
font.pixelSize: 16
|
|
99
|
+
color: backMouse.containsMouse ? Style.colorSurface : Style.colorAccent
|
|
100
|
+
Behavior on color { ColorAnimation { duration: 120 } }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
MouseArea {
|
|
104
|
+
id: backMouse
|
|
105
|
+
anchors.fill: parent
|
|
106
|
+
hoverEnabled: true
|
|
107
|
+
cursorShape: Qt.PointingHandCursor
|
|
108
|
+
onClicked: root.stackView.pop()
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Text {
|
|
113
|
+
Layout.fillWidth: true
|
|
114
|
+
text: qsTr("Basic calculation")
|
|
115
|
+
font { family: "Georgia"; pixelSize: 22; weight: Font.DemiBold; letterSpacing: 0.4 }
|
|
116
|
+
color: Style.colorText
|
|
117
|
+
verticalAlignment: Text.AlignVCenter
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ── Fix 4: Arrhenius formula with real superscript ────────────
|
|
122
|
+
Item {
|
|
123
|
+
Layout.fillWidth: true
|
|
124
|
+
Layout.preferredHeight: 50
|
|
125
|
+
Layout.topMargin: 10
|
|
126
|
+
Layout.bottomMargin: 2
|
|
127
|
+
|
|
128
|
+
// "Ω = A · e" at full size, then the exponent raised above
|
|
129
|
+
Row {
|
|
130
|
+
anchors.centerIn: parent
|
|
131
|
+
spacing: 0
|
|
132
|
+
|
|
133
|
+
Text {
|
|
134
|
+
id: mainLeft
|
|
135
|
+
text: "Ω = A · e"
|
|
136
|
+
font { family: "Georgia"; pixelSize: 22; italic: true }
|
|
137
|
+
color: Style.colorText
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Superscript: sits with its bottom aligned to the top
|
|
141
|
+
// third of the main text glyphs
|
|
142
|
+
Text {
|
|
143
|
+
text: "−Eₐ/(R·T)"
|
|
144
|
+
font { family: "Georgia"; pixelSize: 12; italic: true }
|
|
145
|
+
color: Style.colorText
|
|
146
|
+
// Raise by roughly half the main cap-height
|
|
147
|
+
anchors.bottom: mainLeft.top
|
|
148
|
+
anchors.bottomMargin: -mainLeft.height * 0.38
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
Text {
|
|
152
|
+
text: " · Δt"
|
|
153
|
+
font { family: "Georgia"; pixelSize: 22; italic: true }
|
|
154
|
+
color: Style.colorText
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Rectangle {
|
|
160
|
+
Layout.fillWidth: true
|
|
161
|
+
Layout.preferredHeight: 2
|
|
162
|
+
Layout.topMargin: 4
|
|
163
|
+
Layout.bottomMargin: 20
|
|
164
|
+
color: Style.colorAccent
|
|
165
|
+
opacity: 0.25
|
|
166
|
+
radius: 1
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ══════════════════════════════════════════════════════════════
|
|
170
|
+
// SET 1
|
|
171
|
+
// ══════════════════════════════════════════════════════════════
|
|
172
|
+
SectionLabel { text: "Set 1" }
|
|
173
|
+
Item { Layout.preferredHeight: 10 }
|
|
174
|
+
|
|
175
|
+
RowLayout {
|
|
176
|
+
Layout.fillWidth: true
|
|
177
|
+
spacing: 16
|
|
178
|
+
ParamField { id: a1Field; label: "A [1/s]"; defaultValue: "1e13" }
|
|
179
|
+
ParamField { id: ea1Field; label: "Eₐ [J/mol]"; defaultValue: "8e4" }
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
Item { Layout.preferredHeight: 10 }
|
|
183
|
+
|
|
184
|
+
RowLayout {
|
|
185
|
+
Layout.fillWidth: true
|
|
186
|
+
spacing: 16
|
|
187
|
+
// Fix 2: default shows arithmetic expression the user can edit
|
|
188
|
+
ParamField { id: t1Field; label: "T [K]"; defaultValue: "45+273.15" }
|
|
189
|
+
ParamField { id: dt1Field; label: "Δt [s]"; defaultValue: "1" }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
Item { Layout.preferredHeight: 14 }
|
|
193
|
+
|
|
194
|
+
RowLayout {
|
|
195
|
+
Layout.fillWidth: true
|
|
196
|
+
spacing: 14
|
|
197
|
+
|
|
198
|
+
AppButton {
|
|
199
|
+
text: qsTr("Calculate")
|
|
200
|
+
primary: true
|
|
201
|
+
implicitWidth: 110
|
|
202
|
+
onClicked: {
|
|
203
|
+
root.omega1 = root.calcOmega(
|
|
204
|
+
root.parseVal(a1Field.value),
|
|
205
|
+
root.parseVal(ea1Field.value),
|
|
206
|
+
root.parseVal(t1Field.value),
|
|
207
|
+
root.parseVal(dt1Field.value)
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Text {
|
|
213
|
+
text: "Ω₁ ="
|
|
214
|
+
font { family: "Georgia"; pixelSize: 16 }
|
|
215
|
+
color: Style.colorMuted
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
ResultBox { value: root.formatResult(root.omega1) }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Separator
|
|
222
|
+
Rectangle {
|
|
223
|
+
Layout.fillWidth: true
|
|
224
|
+
Layout.preferredHeight: 1
|
|
225
|
+
Layout.topMargin: 20
|
|
226
|
+
Layout.bottomMargin: 20
|
|
227
|
+
color: Style.colorBorder
|
|
228
|
+
opacity: 0.6
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ══════════════════════════════════════════════════════════════
|
|
232
|
+
// SET 2
|
|
233
|
+
// ══════════════════════════════════════════════════════════════
|
|
234
|
+
SectionLabel { text: "Set 2" }
|
|
235
|
+
Item { Layout.preferredHeight: 10 }
|
|
236
|
+
|
|
237
|
+
RowLayout {
|
|
238
|
+
Layout.fillWidth: true
|
|
239
|
+
spacing: 16
|
|
240
|
+
ParamField { id: a2Field; label: "A [1/s]"; defaultValue: "1e13" }
|
|
241
|
+
ParamField { id: ea2Field; label: "Eₐ [J/mol]"; defaultValue: "8e4" }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
Item { Layout.preferredHeight: 10 }
|
|
245
|
+
|
|
246
|
+
RowLayout {
|
|
247
|
+
Layout.fillWidth: true
|
|
248
|
+
spacing: 16
|
|
249
|
+
ParamField { id: t2Field; label: "T [K]"; defaultValue: "45+273.15" }
|
|
250
|
+
ParamField { id: dt2Field; label: "Δt [s]"; defaultValue: "1" }
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
Item { Layout.preferredHeight: 14 }
|
|
254
|
+
|
|
255
|
+
RowLayout {
|
|
256
|
+
Layout.fillWidth: true
|
|
257
|
+
spacing: 14
|
|
258
|
+
|
|
259
|
+
AppButton {
|
|
260
|
+
text: qsTr("Calculate")
|
|
261
|
+
primary: true
|
|
262
|
+
implicitWidth: 110
|
|
263
|
+
onClicked: {
|
|
264
|
+
root.omega2 = root.calcOmega(
|
|
265
|
+
root.parseVal(a2Field.value),
|
|
266
|
+
root.parseVal(ea2Field.value),
|
|
267
|
+
root.parseVal(t2Field.value),
|
|
268
|
+
root.parseVal(dt2Field.value)
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
Text {
|
|
274
|
+
text: "Ω₂ ="
|
|
275
|
+
font { family: "Georgia"; pixelSize: 16 }
|
|
276
|
+
color: Style.colorMuted
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
ResultBox { value: root.formatResult(root.omega2) }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Separator
|
|
283
|
+
Rectangle {
|
|
284
|
+
Layout.fillWidth: true
|
|
285
|
+
Layout.preferredHeight: 1
|
|
286
|
+
Layout.topMargin: 20
|
|
287
|
+
Layout.bottomMargin: 20
|
|
288
|
+
color: Style.colorBorder
|
|
289
|
+
opacity: 0.6
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ══════════════════════════════════════════════════════════════
|
|
293
|
+
// VHS CALCULATION
|
|
294
|
+
// ══════════════════════════════════════════════════════════════
|
|
295
|
+
RowLayout {
|
|
296
|
+
Layout.fillWidth: true
|
|
297
|
+
spacing: 0
|
|
298
|
+
|
|
299
|
+
SectionLabel { text: "VHS calculation" }
|
|
300
|
+
Item { Layout.fillWidth: true }
|
|
301
|
+
|
|
302
|
+
// Help button — hover shows tooltip, no click action
|
|
303
|
+
Rectangle {
|
|
304
|
+
id: helpBtn
|
|
305
|
+
implicitWidth: 28; implicitHeight: 28
|
|
306
|
+
radius: 14
|
|
307
|
+
color: "transparent"
|
|
308
|
+
border.color: helpHover.hovered ? Style.colorAccent : Style.colorMuted
|
|
309
|
+
border.width: 1.5
|
|
310
|
+
Behavior on border.color { ColorAnimation { duration: 120 } }
|
|
311
|
+
|
|
312
|
+
Text {
|
|
313
|
+
anchors.centerIn: parent
|
|
314
|
+
text: "?"
|
|
315
|
+
font { family: "Georgia"; pixelSize: 14; weight: Font.Medium }
|
|
316
|
+
color: helpHover.hovered ? Style.colorAccent : Style.colorMuted
|
|
317
|
+
Behavior on color { ColorAnimation { duration: 120 } }
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
HoverHandler { id: helpHover; cursorShape: Qt.WhatsThisCursor }
|
|
321
|
+
|
|
322
|
+
ToolTip {
|
|
323
|
+
visible: helpHover.hovered
|
|
324
|
+
// Small delay so it doesn't flash on quick pass-overs
|
|
325
|
+
delay: 400
|
|
326
|
+
timeout: 8000
|
|
327
|
+
contentItem: Text {
|
|
328
|
+
text: "A simple formula taken from\n"
|
|
329
|
+
+ "\"Variable heat shock response model for medical laser procedures\"\n"
|
|
330
|
+
+ "article, whose intention is to generalise the Arrhenius calculation\n"
|
|
331
|
+
+ "for cases where you have short temperature peaks."
|
|
332
|
+
font { family: "Georgia"; pixelSize: 12 }
|
|
333
|
+
color: "#222222"
|
|
334
|
+
wrapMode: Text.WordWrap
|
|
335
|
+
}
|
|
336
|
+
background: Rectangle {
|
|
337
|
+
color: "#FFFBC8" // classic tooltip yellow
|
|
338
|
+
border.color: "#C8B400"
|
|
339
|
+
border.width: 1
|
|
340
|
+
radius: 4
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ── Fix 4: VHS formula with real superscripts ─────────────────
|
|
347
|
+
Item {
|
|
348
|
+
Layout.fillWidth: true
|
|
349
|
+
Layout.preferredHeight: 46
|
|
350
|
+
Layout.topMargin: 8
|
|
351
|
+
Layout.bottomMargin: 14
|
|
352
|
+
|
|
353
|
+
Row {
|
|
354
|
+
anchors.centerIn: parent
|
|
355
|
+
spacing: 0
|
|
356
|
+
|
|
357
|
+
// (1/Ω_vhs)
|
|
358
|
+
Text {
|
|
359
|
+
id: vhsBase
|
|
360
|
+
text: "(1/Ω_vhs)"
|
|
361
|
+
font { family: "Georgia"; pixelSize: 20; italic: true; weight: Font.Bold }
|
|
362
|
+
color: Style.colorText
|
|
363
|
+
}
|
|
364
|
+
// ^p
|
|
365
|
+
Text {
|
|
366
|
+
text: "p"
|
|
367
|
+
font { family: "Georgia"; pixelSize: 12; italic: true; weight: Font.Bold }
|
|
368
|
+
color: Style.colorText
|
|
369
|
+
anchors.bottom: vhsBase.top
|
|
370
|
+
anchors.bottomMargin: -vhsBase.height * 0.4
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
Text {
|
|
374
|
+
id: vhsMid
|
|
375
|
+
text: " = (1/Ω₁)"
|
|
376
|
+
font { family: "Georgia"; pixelSize: 20; italic: true; weight: Font.Bold }
|
|
377
|
+
color: Style.colorText
|
|
378
|
+
}
|
|
379
|
+
Text {
|
|
380
|
+
text: "p"
|
|
381
|
+
font { family: "Georgia"; pixelSize: 12; italic: true; weight: Font.Bold }
|
|
382
|
+
color: Style.colorText
|
|
383
|
+
anchors.bottom: vhsMid.top
|
|
384
|
+
anchors.bottomMargin: -vhsMid.height * 0.4
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
Text {
|
|
388
|
+
id: vhsRight
|
|
389
|
+
text: " + (1/Ω₂)"
|
|
390
|
+
font { family: "Georgia"; pixelSize: 20; italic: true; weight: Font.Bold }
|
|
391
|
+
color: Style.colorText
|
|
392
|
+
}
|
|
393
|
+
Text {
|
|
394
|
+
text: "p"
|
|
395
|
+
font { family: "Georgia"; pixelSize: 12; italic: true; weight: Font.Bold }
|
|
396
|
+
color: Style.colorText
|
|
397
|
+
anchors.bottom: vhsRight.top
|
|
398
|
+
anchors.bottomMargin: -vhsRight.height * 0.4
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Fix 3: p field on its own row (half-width)
|
|
404
|
+
RowLayout {
|
|
405
|
+
Layout.fillWidth: true
|
|
406
|
+
spacing: 16
|
|
407
|
+
ParamField { id: pField; label: "p"; defaultValue: "0.15" }
|
|
408
|
+
Item { Layout.fillWidth: true } // takes the other half
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
Item { Layout.preferredHeight: 10 }
|
|
412
|
+
|
|
413
|
+
// Fix 3: Calculate + Ω_vhs result on the row below
|
|
414
|
+
RowLayout {
|
|
415
|
+
Layout.fillWidth: true
|
|
416
|
+
spacing: 14
|
|
417
|
+
|
|
418
|
+
AppButton {
|
|
419
|
+
text: qsTr("Calculate")
|
|
420
|
+
primary: true
|
|
421
|
+
implicitWidth: 110
|
|
422
|
+
onClicked: {
|
|
423
|
+
var p = root.parseVal(pField.value)
|
|
424
|
+
if (isNaN(root.omega1) || isNaN(root.omega2) ||
|
|
425
|
+
root.omega1 === 0 || root.omega2 === 0 || p === 0) {
|
|
426
|
+
root.omegaVHS = NaN
|
|
427
|
+
return
|
|
428
|
+
}
|
|
429
|
+
var inv = Math.pow(1.0 / root.omega1, p) +
|
|
430
|
+
Math.pow(1.0 / root.omega2, p)
|
|
431
|
+
root.omegaVHS = 1.0 / Math.pow(inv, 1.0 / p)
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
Text {
|
|
436
|
+
text: "Ω_vhs ="
|
|
437
|
+
font { family: "Georgia"; pixelSize: 16 }
|
|
438
|
+
color: Style.colorMuted
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
ResultBox { value: root.formatResult(root.omegaVHS) }
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
Item { Layout.preferredHeight: 36 }
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
449
|
+
// Reusable inline components
|
|
450
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
451
|
+
|
|
452
|
+
component SectionLabel: Text {
|
|
453
|
+
font { family: "Georgia"; pixelSize: 15; weight: Font.DemiBold }
|
|
454
|
+
color: Style.colorText
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Fix 2: inputMethodHints removed so arithmetic expressions are typeable
|
|
458
|
+
component ParamField: ColumnLayout {
|
|
459
|
+
id: pf
|
|
460
|
+
property string label: ""
|
|
461
|
+
property string defaultValue: ""
|
|
462
|
+
property alias value: pfInput.text
|
|
463
|
+
spacing: 4
|
|
464
|
+
Layout.fillWidth: true
|
|
465
|
+
|
|
466
|
+
Text {
|
|
467
|
+
text: pf.label
|
|
468
|
+
font { family: "Georgia"; pixelSize: 14 }
|
|
469
|
+
color: Style.colorMuted
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
Rectangle {
|
|
473
|
+
Layout.fillWidth: true
|
|
474
|
+
implicitHeight: 34
|
|
475
|
+
radius: 5
|
|
476
|
+
color: Style.colorSurface
|
|
477
|
+
border.color: pfInput.activeFocus ? Style.colorAccent : Style.colorBorder
|
|
478
|
+
border.width: pfInput.activeFocus ? 1.5 : 1
|
|
479
|
+
Behavior on border.color { ColorAnimation { duration: 120 } }
|
|
480
|
+
|
|
481
|
+
TextInput {
|
|
482
|
+
id: pfInput
|
|
483
|
+
anchors { fill: parent; leftMargin: 8; rightMargin: 8 }
|
|
484
|
+
verticalAlignment: TextInput.AlignVCenter
|
|
485
|
+
text: pf.defaultValue
|
|
486
|
+
font { family: "Georgia"; pixelSize: 15 }
|
|
487
|
+
color: Style.colorText
|
|
488
|
+
selectByMouse: true
|
|
489
|
+
// inputMethodHints intentionally omitted — allows +−*/
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
component ResultBox: Rectangle {
|
|
495
|
+
property string value: "—"
|
|
496
|
+
Layout.fillWidth: true
|
|
497
|
+
implicitHeight: 34
|
|
498
|
+
radius: 5
|
|
499
|
+
color: Style.colorBg
|
|
500
|
+
border.color: Style.colorBorder
|
|
501
|
+
border.width: 1
|
|
502
|
+
|
|
503
|
+
Text {
|
|
504
|
+
anchors { fill: parent; leftMargin: 8; rightMargin: 8 }
|
|
505
|
+
verticalAlignment: Text.AlignVCenter
|
|
506
|
+
text: parent.value
|
|
507
|
+
font { family: "Georgia"; pixelSize: 15; italic: parent.value === "—" }
|
|
508
|
+
color: parent.value === "—" ? Style.colorMuted : Style.colorAccent
|
|
509
|
+
elide: Text.ElideRight
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import QtQuick.Layouts
|
|
4
|
+
import ArrheniusCalculator
|
|
5
|
+
|
|
6
|
+
// ── Home / Main view ──────────────────────────────────────────────────────
|
|
7
|
+
Item {
|
|
8
|
+
id: root
|
|
9
|
+
|
|
10
|
+
// Attached property — available automatically when this item is inside a StackView
|
|
11
|
+
property StackView stackView: StackView.view as StackView
|
|
12
|
+
|
|
13
|
+
// ── Layout ────────────────────────────────────────────────────────────
|
|
14
|
+
ColumnLayout {
|
|
15
|
+
anchors {
|
|
16
|
+
fill: parent
|
|
17
|
+
margins: 36
|
|
18
|
+
}
|
|
19
|
+
spacing: 28
|
|
20
|
+
|
|
21
|
+
// ── Title ─────────────────────────────────────────────────────────
|
|
22
|
+
Text {
|
|
23
|
+
Layout.fillWidth: true
|
|
24
|
+
text: qsTr("Arrhenius Calculator")
|
|
25
|
+
font {
|
|
26
|
+
family: "Georgia"
|
|
27
|
+
pixelSize: 26
|
|
28
|
+
weight: Font.DemiBold
|
|
29
|
+
letterSpacing: 0.5
|
|
30
|
+
}
|
|
31
|
+
color: Style.colorText
|
|
32
|
+
horizontalAlignment: Text.AlignHCenter
|
|
33
|
+
wrapMode: Text.WordWrap
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Thin accent rule under the title
|
|
37
|
+
Rectangle {
|
|
38
|
+
Layout.fillWidth: true
|
|
39
|
+
Layout.preferredHeight: 2
|
|
40
|
+
color: Style.colorAccent
|
|
41
|
+
opacity: 0.25
|
|
42
|
+
radius: 1
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ── Image placeholder ─────────────────────────────────────────────
|
|
46
|
+
Rectangle {
|
|
47
|
+
Layout.fillWidth: true
|
|
48
|
+
Layout.fillHeight: true
|
|
49
|
+
color: Style.colorSurface
|
|
50
|
+
border.color: Style.colorBorder
|
|
51
|
+
border.width: 1
|
|
52
|
+
radius: 8
|
|
53
|
+
|
|
54
|
+
// Dashed inner border hint
|
|
55
|
+
Rectangle {
|
|
56
|
+
anchors { fill: parent; margins: 10 }
|
|
57
|
+
color: "transparent"
|
|
58
|
+
border.color: Style.colorBorder
|
|
59
|
+
border.width: 1
|
|
60
|
+
radius: 4
|
|
61
|
+
opacity: 0.6
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Column {
|
|
65
|
+
anchors.centerIn: parent
|
|
66
|
+
spacing: 10
|
|
67
|
+
|
|
68
|
+
Canvas {
|
|
69
|
+
width: 56
|
|
70
|
+
height: 56
|
|
71
|
+
anchors.horizontalCenter: parent.horizontalCenter
|
|
72
|
+
onPaint: {
|
|
73
|
+
const ctx = getContext("2d")
|
|
74
|
+
ctx.clearRect(0, 0, width, height)
|
|
75
|
+
ctx.strokeStyle = Style.colorBorder
|
|
76
|
+
ctx.lineWidth = 1.5
|
|
77
|
+
ctx.beginPath()
|
|
78
|
+
ctx.rect(2, 2, width - 4, height - 4)
|
|
79
|
+
ctx.fillStyle = Style.colorBg
|
|
80
|
+
ctx.fill()
|
|
81
|
+
ctx.stroke()
|
|
82
|
+
ctx.fillStyle = Style.colorBorder
|
|
83
|
+
ctx.beginPath()
|
|
84
|
+
ctx.moveTo(8, height - 10)
|
|
85
|
+
ctx.lineTo(28, 16)
|
|
86
|
+
ctx.lineTo(48, height - 10)
|
|
87
|
+
ctx.closePath()
|
|
88
|
+
ctx.fill()
|
|
89
|
+
ctx.beginPath()
|
|
90
|
+
ctx.arc(44, 13, 7, 0, 2 * Math.PI)
|
|
91
|
+
ctx.fill()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Text {
|
|
96
|
+
anchors.horizontalCenter: parent.horizontalCenter
|
|
97
|
+
text: qsTr("Image placeholder")
|
|
98
|
+
font { family: "Georgia"; pixelSize: 13; italic: true }
|
|
99
|
+
color: Style.colorMuted
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ── Button row ────────────────────────────────────────────────────
|
|
105
|
+
RowLayout {
|
|
106
|
+
Layout.fillWidth: true
|
|
107
|
+
spacing: 16
|
|
108
|
+
|
|
109
|
+
AppButton {
|
|
110
|
+
Layout.fillWidth: true
|
|
111
|
+
text: qsTr("Launch")
|
|
112
|
+
primary: true
|
|
113
|
+
onClicked: root.stackView.push(Qt.resolvedUrl("OptionView.qml"))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
AppButton {
|
|
117
|
+
Layout.fillWidth: true
|
|
118
|
+
text: qsTr("About")
|
|
119
|
+
primary: false
|
|
120
|
+
onClicked: root.stackView.push(Qt.resolvedUrl("AboutView.qml"))
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Item { Layout.preferredHeight: 4 }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import ArrheniusCalculator
|
|
4
|
+
|
|
5
|
+
ApplicationWindow {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
minimumWidth: 480
|
|
9
|
+
minimumHeight: 560
|
|
10
|
+
width: 480
|
|
11
|
+
height: 560
|
|
12
|
+
visible: true
|
|
13
|
+
title: qsTr("Arrhenius Calculator")
|
|
14
|
+
|
|
15
|
+
background: Rectangle { color: Style.colorBg }
|
|
16
|
+
|
|
17
|
+
// ── Navigation stack ──────────────────────────────────────────────────
|
|
18
|
+
StackView {
|
|
19
|
+
id: stack
|
|
20
|
+
anchors.fill: parent
|
|
21
|
+
|
|
22
|
+
// No built-in transition animation needed — define a clean fade
|
|
23
|
+
pushEnter: Transition {
|
|
24
|
+
PropertyAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
|
|
25
|
+
}
|
|
26
|
+
pushExit: Transition {
|
|
27
|
+
PropertyAnimation { property: "opacity"; from: 1; to: 0; duration: 200 }
|
|
28
|
+
}
|
|
29
|
+
popEnter: Transition {
|
|
30
|
+
PropertyAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
|
|
31
|
+
}
|
|
32
|
+
popExit: Transition {
|
|
33
|
+
PropertyAnimation { property: "opacity"; from: 1; to: 0; duration: 200 }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
initialItem: HomeView { }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
import QtQuick.Layouts
|
|
4
|
+
import ArrheniusCalculator
|
|
5
|
+
|
|
6
|
+
// ── Calculation selector view ─────────────────────────────────────────────
|
|
7
|
+
Item {
|
|
8
|
+
id: root
|
|
9
|
+
|
|
10
|
+
property StackView stackView: StackView.view as StackView
|
|
11
|
+
|
|
12
|
+
ColumnLayout {
|
|
13
|
+
anchors {
|
|
14
|
+
fill: parent
|
|
15
|
+
margins: 36
|
|
16
|
+
}
|
|
17
|
+
spacing: 24
|
|
18
|
+
|
|
19
|
+
// ── Header row: back button + title ───────────────────────────────
|
|
20
|
+
RowLayout {
|
|
21
|
+
Layout.fillWidth: true
|
|
22
|
+
spacing: 12
|
|
23
|
+
|
|
24
|
+
Rectangle {
|
|
25
|
+
id: backBtn
|
|
26
|
+
implicitWidth: 36
|
|
27
|
+
implicitHeight: 36
|
|
28
|
+
radius: 18
|
|
29
|
+
color: backMouse.containsMouse
|
|
30
|
+
? Style.colorAccent
|
|
31
|
+
: "transparent"
|
|
32
|
+
border.color: Style.colorAccent
|
|
33
|
+
border.width: 1.5
|
|
34
|
+
|
|
35
|
+
Behavior on color {
|
|
36
|
+
ColorAnimation { duration: 120 }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Text {
|
|
40
|
+
anchors.centerIn: parent
|
|
41
|
+
text: "←"
|
|
42
|
+
font.pixelSize: 16
|
|
43
|
+
color: backMouse.containsMouse
|
|
44
|
+
? Style.colorSurface
|
|
45
|
+
: Style.colorAccent
|
|
46
|
+
|
|
47
|
+
Behavior on color {
|
|
48
|
+
ColorAnimation { duration: 120 }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
MouseArea {
|
|
53
|
+
id: backMouse
|
|
54
|
+
anchors.fill: parent
|
|
55
|
+
hoverEnabled: true
|
|
56
|
+
cursorShape: Qt.PointingHandCursor
|
|
57
|
+
onClicked: root.stackView.pop()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Text {
|
|
62
|
+
Layout.fillWidth: true
|
|
63
|
+
text: qsTr("Select Calculation")
|
|
64
|
+
font {
|
|
65
|
+
family: "Georgia"
|
|
66
|
+
pixelSize: 26
|
|
67
|
+
weight: Font.DemiBold
|
|
68
|
+
letterSpacing: 0.5
|
|
69
|
+
}
|
|
70
|
+
color: Style.colorText
|
|
71
|
+
horizontalAlignment: Text.AlignLeft
|
|
72
|
+
verticalAlignment: Text.AlignVCenter
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Thin accent rule
|
|
77
|
+
Rectangle {
|
|
78
|
+
Layout.fillWidth: true
|
|
79
|
+
Layout.preferredHeight: 2
|
|
80
|
+
color: Style.colorAccent
|
|
81
|
+
opacity: 0.25
|
|
82
|
+
radius: 1
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── Calculation type buttons ───────────────────────────────────────
|
|
86
|
+
ColumnLayout {
|
|
87
|
+
Layout.fillWidth: true
|
|
88
|
+
spacing: 12
|
|
89
|
+
|
|
90
|
+
AppButton {
|
|
91
|
+
Layout.fillWidth: true
|
|
92
|
+
text: qsTr("Basic calculation")
|
|
93
|
+
primary: false
|
|
94
|
+
onClicked: root.stackView.push(Qt.resolvedUrl("BasicCalculationView.qml"))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
AppButton {
|
|
98
|
+
Layout.fillWidth: true
|
|
99
|
+
text: qsTr("Function calculation")
|
|
100
|
+
primary: false
|
|
101
|
+
onClicked: { /* TODO */ }
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ── Spacer ────────────────────────────────────────────────────────
|
|
106
|
+
Item { Layout.fillHeight: true }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: arrheniuscalculator
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A simple GUI tool for calculating Arrhenius integral.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: pyside6
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
|
|
11
|
+
# ArrheniusCalculator
|
|
12
|
+
|
|
13
|
+
The intention of this project is to develop a simple QML GUI application that will calculate the Arrhenius integral for various cases (tabular data, functional data, etc.).
|
|
14
|
+
|
|
15
|
+
The project is currently in the process of being published on pypi package index, so except installation instructions to not work correctly.
|
|
16
|
+
|
|
17
|
+
## Option 1: Install from PyPi
|
|
18
|
+
|
|
19
|
+
### Option a: Using uv
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add arrheniuscalculator
|
|
23
|
+
uv run arrheniuscalculator
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Option b: Using pip
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install arrheniuscalculator
|
|
30
|
+
arrheniuscalculator
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Option 2: Installation from source
|
|
34
|
+
|
|
35
|
+
### Option a: Using uv
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
39
|
+
cd ArrheniusCalculator
|
|
40
|
+
uv sync
|
|
41
|
+
uv run python -m arrheniuscalculator.main
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option b: Using pip
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/TZ387/ArrheniusCalculator.git
|
|
48
|
+
cd ArrheniusCalculator
|
|
49
|
+
|
|
50
|
+
python -m venv .venv
|
|
51
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
52
|
+
|
|
53
|
+
pip install -e .
|
|
54
|
+
python -m arrheniuscalculator.main
|
|
55
|
+
```
|
|
56
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
arrheniuscalculator/__init__.py
|
|
5
|
+
arrheniuscalculator/main.py
|
|
6
|
+
arrheniuscalculator.egg-info/PKG-INFO
|
|
7
|
+
arrheniuscalculator.egg-info/SOURCES.txt
|
|
8
|
+
arrheniuscalculator.egg-info/dependency_links.txt
|
|
9
|
+
arrheniuscalculator.egg-info/entry_points.txt
|
|
10
|
+
arrheniuscalculator.egg-info/requires.txt
|
|
11
|
+
arrheniuscalculator.egg-info/top_level.txt
|
|
12
|
+
arrheniuscalculator/qml/AboutView.qml
|
|
13
|
+
arrheniuscalculator/qml/AppButton.qml
|
|
14
|
+
arrheniuscalculator/qml/BasicCalculationView.qml
|
|
15
|
+
arrheniuscalculator/qml/HomeView.qml
|
|
16
|
+
arrheniuscalculator/qml/Main.qml
|
|
17
|
+
arrheniuscalculator/qml/OptionView.qml
|
|
18
|
+
arrheniuscalculator/qml/ArrheniusCalculator/Style.qml
|
|
19
|
+
arrheniuscalculator/qml/ArrheniusCalculator/qmldir
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyside6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
arrheniuscalculator
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "arrheniuscalculator"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "A simple GUI tool for calculating Arrhenius integral."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"pyside6",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.setuptools.packages.find]
|
|
16
|
+
where = ["."]
|
|
17
|
+
include = ["arrheniuscalculator*"]
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.package-data]
|
|
20
|
+
"arrheniuscalculator" = [
|
|
21
|
+
"qml/*.qml",
|
|
22
|
+
"qml/ArrheniusCalculator/*"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
arrheniuscalculator = "arrheniuscalculator.main:main"
|