feat: fortune cookie v1.0 - qml ui und python backend implementiert

This commit is contained in:
darklithium
2026-06-01 21:16:26 +02:00
parent 9123c7465f
commit 114ccc6c4f
6 changed files with 397 additions and 307 deletions
+113 -79
View File
@@ -1,127 +1,161 @@
/*
* UNIVERSELLER QML Haupt-Template für Ubuntu Touch Apps
* Basierend auf metime und Referenz-App (Version 1.7)
*
* VERWENDUNG:
* 1. Kopiere diese Datei nach qml/Main.qml
* 2. Ersetze '<app-name>' mit deinem App-Namen
* 3. Passe Titel und UI-Elemente an
* 4. Füge deine Python-Modul-Imports hinzu
*
* WICHTIG (1.7):
* - Immer QtQuick 2.7 und Lomiri.Components 1.3 verwenden
* - QtQuick.Layouts 1.3 für Layouts importieren
* - fontSize als STRING verwenden ("large", "x-large", "medium")
* - PageFooter existiert NICHT → als Label implementieren
* - PyOtherSide mit Qt.resolvedUrl("../src") einbinden
*/
import QtQuick 2.7
import QtQuick.Layouts 1.3 // ✅ NEU 1.7: Notwendig für ColumnLayout!
import QtQuick.Layouts 1.3
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import io.thp.pyotherside 1.4
MainView {
id: root
objectName: 'mainView'
// APP META-DATEN (Anpassen!)
applicationName: '<app-name>.darklithium'
applicationName: "fortunecookie.darklithium"
width: units.gu(45)
height: units.gu(75)
theme.name: "Lomiri.Components.Themes.SuruDark"
// ====================================================================
// PYTHON-MODUL (STANDARD 1.7)
// 1. PYTHON-MODUL (STANDARD 1.7)
// ====================================================================
Python {
id: py
Component.onCompleted: {
// ✅ STANDARD 1.7: Qt.resolvedUrl funktioniert!
addImportPath(Qt.resolvedUrl("../src"));
importModule('<app-name>', function() {
console.log("Python-Modul <app-name> geladen");
// Initialisierung nach erfolgreicher Modul-Ladung
statusLabel.text = py.call_sync("<app-name>.get_status_text", []);
footerLabel.text = py.call_sync("<app-name>.get_platform", []);
importModule("fortunecookie", function() {
console.log("Python-Modul fortunecookie geladen");
// Initialisierung
currentFortuneLabel.text = py.call_sync("fortunecookie.get_initial_fortune", []);
cookieImage.source = "assets/cookie_closed.png";
fortuneOpened = false;
});
}
onError: {
console.log('Python Fehler: ' + traceback);
}
}
// ====================================================================
// HAUPTSSeITE (Anpassen nach Bedarf)
// 2. APP-ZUSTAND (STANDARD 1.7)
// ====================================================================
property bool fortuneOpened: false
property string currentFortune: ""
property bool musicPlaying: false
// ====================================================================
// 3. HAUPTSEITE
// ====================================================================
Page {
id: mainPage
anchors.fill: parent
// Header
header: PageHeader {
title: "<App-Name>" // App-Name anpassen
title: "Fortune Cookie"
}
// Hauptinhalt (ColumnLayout für vertikale Anordnung)
ColumnLayout {
anchors.fill: parent
spacing: units.gu(2) // 2 GU Abstand zwischen Elementen
// ================================================================
// COOKIE & SPRUCH
// ================================================================
// Status-Label (optional)
Label {
id: statusLabel
text: "Lade..."
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
fontSize: "large" // ✅ NEU 1.7: String-Wert!
// Cookie-Image (zentral)
Image {
id: cookieImage
anchors.centerIn: parent
width: units.gu(30)
height: units.gu(30)
source: fortuneOpened ? "assets/cookie_open.png" : "assets/cookie_closed.png"
// Wisch-Geste nach oben
MouseArea {
anchors.fill: parent
property real startY: 0
onPressed: {
startY = mouseY
}
onReleased: {
// Ende der Geste - pruufen ob nach oben gewischt
if (mouseY < startY - units.gu(2)) {
// Wisch nach oben -> Cookie oeffnen
py.call("fortunecookie.open_fortune", [], function() {
fortuneOpened = true;
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
currentFortuneLabel.text = currentFortune;
cookieImage.source = "assets/cookie_open.png";
});
}
}
}
// Hauptinhalt hier einfügen
// Beispiel: Textfeld
Label {
id: contentLabel
text: "Hier steht Beispieltext"
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
fontSize: "x-large" // ✅ NEU 1.7: String-Wert!
}
// Beispiel: Button
Button {
id: testButton
text: "Test Button"
Layout.fillWidth: false
Layout.preferredWidth: units.gu(20) // 200 DP (Touch-optimiert!)
Layout.preferredHeight: units.gu(8) // 80 DP
// Tap auf Cookie (wenn geschlossen)
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (py) {
py.call("<app-name>.on_button_click", [], function() {
contentLabel.text = py.call_sync("<app-name>.get_content_text", []);
if (!fortuneOpened) {
// Cookie oeffnen (gleiche Funktion wie Wisch nach oben)
py.call("fortunecookie.open_fortune", [], function() {
fortuneOpened = true;
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
currentFortuneLabel.text = currentFortune;
cookieImage.source = "assets/cookie_open.png";
});
}
}
}
}
// ================================================================
// FOOTER (Workaround für Lomiri.Components 1.3)
// ================================================================
// ⚠️ WICHTIG: PageFooter existiert NICHT in Lomiri.Components 1.3!
// Fortune-Text (erscheint nach dem Oeffnen)
Label {
id: footerLabel
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: units.gu(2)
text: "Plattform: ?"
fontSize: "medium" // ✅ NEU 1.7: String-Wert!
id: currentFortuneLabel
anchors {
top: cookieImage.bottom
topMargin: units.gu(2)
left: parent.left
right: parent.right
leftMargin: units.gu(2)
rightMargin: units.gu(2)
}
text: ""
fontSize: "large"
horizontalAlignment: Text.AlignHCenter
visible: fortuneOpened
wrapMode: Text.WordWrap
// Tap auf Spruch -> neuer Cookie
MouseArea {
anchors.fill: parent
onClicked: {
py.call("fortunecookie.get_new_fortune", [], function() {
fortuneOpened = false;
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
currentFortuneLabel.text = currentFortune;
cookieImage.source = "assets/cookie_closed.png";
});
}
}
}
// ================================================================
// MUSIK BUTTON (rechts unten)
// ================================================================
Button {
id: musicButton
anchors {
right: parent.right
bottom: parent.bottom
margins: units.gu(2)
}
width: units.gu(8)
height: units.gu(8)
text: musicPlaying ? "\uD83D\uDD07" : "\uD83D\uDD0A"
fontSize: "x-large"
onClicked: {
if (musicPlaying) {
py.call("fortunecookie.stop_music", []);
} else {
py.call("fortunecookie.start_music", []);
}
musicPlaying = !musicPlaying;
}
}
}
}