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.
@@ -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
+
@@ -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,2 @@
1
+ module ArrheniusCalculator
2
+ singleton Style 1.0 Style.qml
@@ -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,2 @@
1
+ [console_scripts]
2
+ arrheniuscalculator = arrheniuscalculator.main:main
@@ -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"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+