From 3deeedff956ddd9c2906a1fc8ba91b1535652145 Mon Sep 17 00:00:00 2001 From: Daniel Ziltener Date: Thu, 3 Mar 2022 12:04:30 +0100 Subject: [PATCH] Update attempts --- examples/examples.org | 190 +++++++++++++++++++++++++++++ qml.core.scm | 45 ++++++- qml.lowlevel.scm | 277 ++++++++++++++++++++++-------------------- 3 files changed, 375 insertions(+), 137 deletions(-) create mode 100644 examples/examples.org diff --git a/examples/examples.org b/examples/examples.org new file mode 100644 index 0000000..9651737 --- /dev/null +++ b/examples/examples.org @@ -0,0 +1,190 @@ +#+TITLE: QML Examples + + +* Hello World +This is a simple "Hello World" program, opening a window and displaying a text. +#+begin_src javascript :tangle helloworld.qml +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +Window { + id: window + visible: true + width: 800 + height: 600 + + Rectangle { + color: "lightgray" + width: 800 + height: 600 + x: 0 + y: 0 + Text { + text: qt("Hello World!") + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + font.pointSize: 24 + font.bold: true + } + } +} +#+end_src + +#+begin_src scheme :tangle helloworld.scm +(import (chicken base) + srfi-18 + (qml core) + coops) + +(gui-application-create) +(define engine (make )) + +(load-url engine (new-QUrl "helloworld.qml")) +(do ((loop #t)) + ((not loop) #t) + (thread-sleep! (seconds->time (+ 0.05 (time->seconds (current-time))))) + (process-events-timed (qevent-loop-process-event-flag process-all-events:) 50)) +#+end_src + +* Signals and Slots +Adapted from https://raymii.org/s/snippets/Cpp_QT_QML_Signals_and_Slots.html + +#+begin_src javascript :tangle signals-slots.qml +import QtQuick 2.11 +import QtQuick.Window 2.11 +import QtQuick.Controls 2.11 + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("QML Signals and slots example - Raymii.org") + + MenuBar { + width: parent.width + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } + + Column { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + spacing: 20 + + Text { + id: info + width: parent.width * 0.9 + wrapMode: Text.WordWrap + text: "QML / C++ binding via signals and slots example program, by Raymii.org. License: GNU GPLv3" + } + + + Text { + id: labelCount + // C++ method Counter::value(). Bound via Q_PROPERTY, updates automatically on change + text: "Counter: " + MyCounter.value + "." + } + + Text { + property int changeCount: 0 + id: labelChanged + text: "Count has changed " + changeCount + " times." + // Receive the valueChanged NOTIFY + Connections { + target: MyCounter + onValueChanged: { + ++labelChanged.changeCount + } + } + } + + Row { + spacing: 20 + Button { + text: qsTr("Increase Counter") + onClicked: ++MyCounter.value + } + + Button { + text: qsTr("Set counter to 10") + // C++ method Counter::setValue(long long), bound via Q_PROPERTY + onClicked: MyCounter.setValue(10) + } + + Button { + text: qsTr("Reset") + onClicked: { + // C++ method Counter::setValue(long long), bound via Q_PROPERTY + MyCounter.setValue(0) + } + } + } + + Row { + spacing: 20 + + Text { + id: setText + text: qsTr("Enter counter value: ") + } + Rectangle { + width: setText.width + height: setText.height + border.width: 1 + border.color: "black" + + TextInput { + id: counterInput + focus: true + text: MyCounter.value + } + } + // Bi-directional binding, entering a number in the textarea updates the + // C++ class, if the C++ class is updated, the textarea is updated as well. + Binding { + target: MyCounter + property: "value" + value: counterInput.text + } + } + } +} +#+end_src + +#+begin_src scheme :tangle signals-slots.scm +(import (chicken base) + srfi-18 + (qml core) + coops + coops-primitive-objects) + +(gui-application-create) +(define engine (make )) + +;; Create counter object + +(define (callback self slotName argv) + (print self " == " slotName " == " argv)) +;; See https://doc.qt.io/qt-5/qmetatype.html for the meta types +(define counter (make-QObject #f "Counter" #f callback + (new-Signals (list (new-Signal "valueChanged" '(int)))) + (new-Slots (list (new-Slot "setValue" 43 '(int)) + (new-Slot "value" 2 '(void)))) + (new-Properties (list (new-Property "value" 2 "value" "setValue" "valueChanged"))))) + +(set-property root-context "MyCounter" counter) + +(load engine (new-QUrl "signals-slots.qml")) + +(do ((loop #t)) + ((not loop) #t) + (thread-sleep! (seconds->time (+ 0.05 (time->seconds (current-time))))) + (process-events-timed (qevent-loop-process-event-flag process-all-events:) 50)) +#+end_src diff --git a/qml.core.scm b/qml.core.scm index 1209277..8f671ca 100644 --- a/qml.core.scm +++ b/qml.core.scm @@ -379,6 +379,29 @@ (define-method (delete-pointer (qv )) (dos_qvariant_delete (ptr qv))) + (define dobject-callbacks (make-hash-table)) + + (define-external (dObjectCallbackHelper (c-pointer self) (c-pointer slotName) (int argc) ((c-pointer c-pointer) argv)) void + (let* ((qobject (hash-table-ref dobject-callbacks self)) + (args (c_array_convert argv argc))) + ((alist-ref callback: dobject-callbacks) (alist-ref object: dobject-callbacks) (qvariant slotName) + (map qvariant args)))) + + (define (make-QObject qobject name qmetaobject signals slots props callback) + @("Creates a new QObject." + (qobject "An instance of or #f") + (qmetaobject "A QMetaObject or #f") + (callback "A procedure of the form (function self slotName -array argv)")) + (let* ((qmeta (if qmetaobject (ptr qmetaobject) (dos_qobject_qmetaobject))) + (qmeta (dos_qmetaobject_create (qml_qmetaobject_superClass) + name signals slots props)) + (qobj (make 'ptr (dos_qobject_create (if (instance-of? qobject ) + (ptr qobject) #f) + qmeta + callback)))) + (hash-table-set! dobject-callbacks (ptr qobj) `((object: . ,qobj) + (callback: . ,callback))) + qobj)) (define-method (signal-emit (qo ) (name ) (paramcount ) (parameters )) (dos_qobject_signal_emit (ptr qo) name paramcount parameters)) (define-method (object-name (qo )) @@ -481,17 +504,29 @@ ;; - Signals (define-class ()) - (define-method (new-Signal (name ) (parameters )) - (make 'obj (dos_signaldefinition_create name (length parameters) (map obj parameters)))) + (define-method (new-Signal (name ) #!rest parameters) + (make + 'obj (dos_signaldefinition_create name (length parameters) + (cdr + (foldl (lambda (coll elem) + (cons (+ (car coll) 1) + (pointer-vector-set! (cdr coll) (car coll) + (object->pointer (object-evict (obj elem)))))) + (cons 0 (make-pointer-vector (length parameters))) parameters))))) (define-class ()) (define-method (new-Signals (defs )) - (make 'ptr (dos_signaldefinitions_create (length defs) (map ptr defs)))) + (make + 'ptr (dos_signaldefinitions_create (length defs) + (foldl (lambda (coll elem) + (cons (+ (car coll) 1) + (pointer-vector-set! (cdr coll) (car coll) (ptr elem)))) + (cons 0 (make-pointer-vector (length defs))) defs)))) (define-method (delete-pointer (sd )) (dos_signaldefinitions_delete (ptr sd))) ;; - Slots (define-class ()) - (define-method (new-Slot (name ) (returnMetaType ) (parameters )) + (define-method (new-Slot (name ) (returnMetaType ) #!rest parameters) (make 'obj (dos_slotdefinition_create name returnMetaType (length parameters) (map obj parameters)))) (define-class ()) (define-method (new-Slots (defs )) @@ -514,6 +549,8 @@ (dos_qqmlcontext_baseUrl (ptr context))) (define-method (set-property (context ) (name ) (qvalue )) (dos_qqmlcontext_setcontextproperty (ptr context) name (ptr qvalue))) + (define-method (set-property (context ) (name ) (qvalue )) + (qml_qqmlcontext_setcontextproperty (ptr context) name (ptr qvalue))) (define-class ()) (define (new-QUrl url) diff --git a/qml.lowlevel.scm b/qml.lowlevel.scm index 869ddbe..6f652d8 100644 --- a/qml.lowlevel.scm +++ b/qml.lowlevel.scm @@ -8,141 +8,144 @@ (import foreigners) (import list-comprehensions) (export DosQEventLoopProcessEventFlagProcessAllEvents - DosQEventLoopProcessEventFlagExcludeUserInputEvents - DosQEventLoopProcessEventFlagProcessExcludeSocketNotifiers - DosQEventLoopProcessEventFlagProcessAllEventsWaitForMoreEvents - DosQtConnectionTypeAutoConnection - DosQtConnectionTypeDirectConnection - DosQtConnectionTypeQueuedConnection - DosQtConnectionTypeBlockingConnection - DosQtConnectionTypeUniqueConnection + DosQEventLoopProcessEventFlagExcludeUserInputEvents + DosQEventLoopProcessEventFlagProcessExcludeSocketNotifiers + DosQEventLoopProcessEventFlagProcessAllEventsWaitForMoreEvents + DosQtConnectionTypeAutoConnection + DosQtConnectionTypeDirectConnection + DosQtConnectionTypeQueuedConnection + DosQtConnectionTypeBlockingConnection + DosQtConnectionTypeUniqueConnection - dos_slot_macro - dos_signal_macro + dos_slot_macro + dos_signal_macro - c_array_convert + c_array_convert - dos_parameterdefinition_create - dos_parameterdefinition_name - dos_signaldefinition_create - dos_signaldefinitions_create - dos_signaldefinitions_delete - dos_slotdefinition_create - dos_slotdefinitions_create - dos_slotdefinitions_delete - dos_propertydefinition_create - dos_propertydefinitions_create - dos_propertydefinitions_delete - dos_qcoreapplication_application_dir_path - dos_qcoreapplication_process_events - dos_qcoreapplication_process_events_timed - dos_qguiapplication_create - dos_qguiapplication_exec - dos_qguiapplication_quit - dos_qguiapplication_delete - dos_qapplication_create - dos_qapplication_exec - dos_qapplication_quit - dos_qapplication_delete - dos_qquickstyle_set_style - dos_qquickstyle_set_fallback_style - dos_qobject_signal_emit - dos_qobject_objectName - dos_qobject_setObjectName - dos_qobject_delete - dos_qobject_deleteLater - dos_qobject_property - dos_qobject_setProperty - qml_qobject_findChild - dos_qobject_connect_lambda_static - dos_qobject_connect_lambda_with_context_static - dos_qobject_connect_static - dos_qobject_disconnect_static - dos_qobject_disconnect_with_connection_static - dos_qvariant_create - dos_qvariant_create_int - dos_qvariant_create_bool - dos_qvariant_create_string - dos_qvariant_create_qobject - dos_qvariant_create_float - dos_qvariant_setInt - dos_qvariant_setBool - dos_qvariant_setFloat - dos_qvariant_setString - dos_qvariant_setQObject - dos_qvariant_toInt - dos_qvariant_toBool - dos_qvariant_toString - dos_qvariant_toFloat - dos_qvariant_toQObject - dos_qvariant_isnull - dos_qvariant_assign - dos_qvariant_create_qvariant - dos_qvariant_delete - dos_qqmlcontext_baseUrl - dos_qqmlcontext_setcontextproperty - dos_qurl_create - dos_qurl_to_string - dos_qurl_isValid - dos_qurl_delete - dos_qpixmap_create - dos_qpixmap_create_width_and_height - dos_qpixmap_create_qpixmap - dos_qpixmap_load - dos_qpixmap_loadFromData - dos_qpixmap_fill - dos_qpixmap_assign - dos_qpixmap_isNull - dos_qpixmap_delete - dos_qquickimageprovider_create - dos_qquickimageprovider_delete - dos_qqmlapplicationengine_create - dos_qqmlapplicationengine_load - dos_qqmlapplicationengine_load_url - dos_qqmlapplicationengine_load_data - dos_qqmlapplicationengine_add_import_path - dos_qqmlapplicationengine_context - qml_qqmlapplicationengine_root - dos_qqmlapplicationengine_addImageProvider - dos_qqmlapplicationengine_delete - dos_qquickview_create - dos_qquickview_show - dos_qquickview_source - dos_qquickview_set_source_url - dos_qquickview_set_source - dos_qquickview_set_resize_mode - dos_qquickview_rootContext - dos_qquickview_delete - dos_qmetaobject_create - dos_qmetaobject_invoke_method - dos_qmetaobject_delete - dos_qmetaobject_connection_delete - dos_qobject_qmetaobject - dos_qabstractitemmodel_qmetaobject - dos_qabstracttablemodel_qmetaobject - dos_qabstractlistmodel_qmetaobject - dos_qmodelindex_create - dos_qmodelindex_create_qmodelindex - dos_qmodelindex_row - dos_qmodelindex_column - dos_qmodelindex_isValid - dos_qmodelindex_data - dos_qmodelindex_parent - dos_qmodelindex_child - dos_qmodelindex_sibling - dos_qmodelindex_assign - dos_qmodelindex_delete - dos_qabstractitemmodel_create - dos_qabstractitemmodel_setData - dos_qabstractitemmodel_flags - dos_qabstractitemmodel_headerData - dos_qabstractlistmodel_create - dos_qabstractlistmodel_index - dos_qabstractlistmodel_parent - dos_qabstractlistmodel_columnCount - dos_qabstracttablemodel_create - dos_qabstracttablemodel_index - dos_qabstracttablemodel_parent) + dos_parameterdefinition_create + dos_parameterdefinition_name + dos_signaldefinition_create + dos_signaldefinitions_create + dos_signaldefinitions_delete + dos_slotdefinition_create + dos_slotdefinitions_create + dos_slotdefinitions_delete + dos_propertydefinition_create + dos_propertydefinitions_create + dos_propertydefinitions_delete + dos_qcoreapplication_application_dir_path + dos_qcoreapplication_process_events + dos_qcoreapplication_process_events_timed + dos_qguiapplication_create + dos_qguiapplication_exec + dos_qguiapplication_quit + dos_qguiapplication_delete + dos_qapplication_create + dos_qapplication_exec + dos_qapplication_quit + dos_qapplication_delete + dos_qquickstyle_set_style + dos_qquickstyle_set_fallback_style + dos_qobject_create + dos_qobject_signal_emit + dos_qobject_objectName + dos_qobject_setObjectName + dos_qobject_delete + dos_qobject_deleteLater + dos_qobject_property + dos_qobject_setProperty + qml_qobject_findChild + dos_qobject_connect_lambda_static + dos_qobject_connect_lambda_with_context_static + dos_qobject_connect_static + dos_qobject_disconnect_static + dos_qobject_disconnect_with_connection_static + dos_qvariant_create + dos_qvariant_create_int + dos_qvariant_create_bool + dos_qvariant_create_string + dos_qvariant_create_qobject + dos_qvariant_create_float + dos_qvariant_setInt + dos_qvariant_setBool + dos_qvariant_setFloat + dos_qvariant_setString + dos_qvariant_setQObject + dos_qvariant_toInt + dos_qvariant_toBool + dos_qvariant_toString + dos_qvariant_toFloat + dos_qvariant_toQObject + dos_qvariant_isnull + dos_qvariant_assign + dos_qvariant_create_qvariant + dos_qvariant_delete + dos_qqmlcontext_baseUrl + dos_qqmlcontext_setcontextproperty + qml_qqmlcontext_setcontextproperty + dos_qurl_create + dos_qurl_to_string + dos_qurl_isValid + dos_qurl_delete + dos_qpixmap_create + dos_qpixmap_create_width_and_height + dos_qpixmap_create_qpixmap + dos_qpixmap_load + dos_qpixmap_loadFromData + dos_qpixmap_fill + dos_qpixmap_assign + dos_qpixmap_isNull + dos_qpixmap_delete + dos_qquickimageprovider_create + dos_qquickimageprovider_delete + dos_qqmlapplicationengine_create + dos_qqmlapplicationengine_load + dos_qqmlapplicationengine_load_url + dos_qqmlapplicationengine_load_data + dos_qqmlapplicationengine_add_import_path + dos_qqmlapplicationengine_context + qml_qqmlapplicationengine_root + dos_qqmlapplicationengine_addImageProvider + dos_qqmlapplicationengine_delete + dos_qquickview_create + dos_qquickview_show + dos_qquickview_source + dos_qquickview_set_source_url + dos_qquickview_set_source + dos_qquickview_set_resize_mode + dos_qquickview_rootContext + dos_qquickview_delete + dos_qmetaobject_create + qml_qmetaobject_superClass + dos_qmetaobject_invoke_method + dos_qmetaobject_delete + dos_qmetaobject_connection_delete + dos_qobject_qmetaobject + dos_qabstractitemmodel_qmetaobject + dos_qabstracttablemodel_qmetaobject + dos_qabstractlistmodel_qmetaobject + dos_qmodelindex_create + dos_qmodelindex_create_qmodelindex + dos_qmodelindex_row + dos_qmodelindex_column + dos_qmodelindex_isValid + dos_qmodelindex_data + dos_qmodelindex_parent + dos_qmodelindex_child + dos_qmodelindex_sibling + dos_qmodelindex_assign + dos_qmodelindex_delete + dos_qabstractitemmodel_create + dos_qabstractitemmodel_setData + dos_qabstractitemmodel_flags + dos_qabstractitemmodel_headerData + dos_qabstractlistmodel_create + dos_qabstractlistmodel_index + dos_qabstractlistmodel_parent + dos_qabstractlistmodel_columnCount + dos_qabstracttablemodel_create + dos_qabstracttablemodel_index + dos_qabstracttablemodel_parent) (begin (foreign-declare "#include ") (foreign-declare "#include ") @@ -282,7 +285,7 @@ ;; Helpers (define c_array_get (foreign-lambda* (c-pointer DosQVariant) (((c-pointer (c-pointer DosQVariant)) array) - (int index)) + (int index)) "C_return(array[index]);")) (define (c_array_convert c-array num-items) @@ -540,6 +543,11 @@ (c-string name) ((c-pointer DosQVariant) value)) "dos_qqmlcontext_setcontextproperty(vptr, name, value);")) + (define qml_qqmlcontext_setcontextproperty + (foreign-lambda* void (((c-pointer DosQQmlContext) vptr) + (c-string name) + ((c-pointer DosQObject) value)) + "dos_qqmlcontext_setcontextproperty(vptr, name, value);")) ;; String (define dos_chararray_delete @@ -676,6 +684,9 @@ ((c-pointer SlotDefinitions) slotDefinitions) ((c-pointer PropertyDefinitions) propertyDefinitions)) "C_return(dos_qmetaobject_create(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions));")) + (define qml_qmetaobject_superClass + (foreign-lambda* (c-pointer DosQMetaObject) (((c-pointer DosQMetaObject) qMetaObject)) + "C_return((DosQMetaObject*)((QMetaObject*)qMetaObject)->superClass());")) (define dos_qmetaobject_delete (foreign-lambda* void (((c-pointer DosQMetaObject) vptr)) "dos_qmetaobject_delete(vptr);"))