add convenience macro WITH-ROOT-ITEM (for e.g. QML Repeater items with identical object names)

This commit is contained in:
pls.153 2022-10-31 20:28:17 +01:00
parent 5e529e7579
commit 9271cdc13a
4 changed files with 33 additions and 27 deletions

View file

@ -13,7 +13,7 @@ conversions, as long as you only use `bool`, `long`, `double`, `QString`,
`QByteArray` or (nested) `QVariant` lists of mentioned types. `QByteArray` or (nested) `QVariant` lists of mentioned types.
For the complete list of marshalled types please see `toQVariant()` and For the complete list of marshalled types please see `toQVariant()` and
`from_qvariant` in [marshal.cpp](../src/cpp/marshal.cpp). `from_qvariant()` in [marshal.cpp](../src/cpp/marshal.cpp).

View file

@ -44,9 +44,9 @@
<b>find-quick-item (object-name)</b> <b>find-quick-item (object-name)</b>
Finds the first QQuickItem matching OBJECT-NAME. Locally set *ROOT-ITEM* if Finds the first QQuickItem matching OBJECT-NAME.
you want to find items inside a specific item, like in a QML Repeater. See See also WITH-ROOT-ITEM if you want to find items inside a specific item,
also note in sources. like in a QML Repeater.
<b>pixel-ratio ()</b> <b>pixel-ratio ()</b>
@ -294,6 +294,17 @@
(populate-item-model))) (populate-item-model)))
<b>with-root-item (root-item)</b>
Say you have a Repeater QML item with multiple instances of the same
QQuickItem. The children of those QQuickItems all have the same object names,
respectively. In order to access those child items, we need to search in one
specific item of the Repeater.
(with-root-item (q! |itemAt| ui:*repeater* 0)
(q< |text| ui:*edit*))
</pre> </pre>
</body> </body>
</html> </html>

View file

@ -58,6 +58,7 @@
#:set-clipboard-text #:set-clipboard-text
#:tr #:tr
#:view-status-changed #:view-status-changed
#:with-root-item
#:!)) #:!))
(defpackage :qml-user (defpackage :qml-user

View file

@ -29,35 +29,29 @@
(defun find-quick-item (object-name) (defun find-quick-item (object-name)
"args: (object-name) "args: (object-name)
Finds the first QQuickItem matching OBJECT-NAME. Locally set *ROOT-ITEM* if Finds the first QQuickItem matching OBJECT-NAME.
you want to find items inside a specific item, like in a QML Repeater. See See also WITH-ROOT-ITEM if you want to find items inside a specific item,
also note in sources." like in a QML Repeater."
;;
;; When to use *ROOT-ITEM*
;;
;; Say you have a Repeater QML item with multiple instances of the same
;; QQuickItem. The children of those QQuickItems all have the same object
;; names, respectively. In order to access those child items, we need to
;; search in the specific item of the Repeater.
;;
;; So, we locally set (not bind, see note N.B.) *ROOT-ITEM* in order to find
;; a specific child item inside the Repeater:
;;
;; (setf qml:*root-item* (q! |itemAt| ui:*repeater* 0)) ; (1) set
;; ;; everything we do here will only affect children of the first
;; ;; item in ui:*repeater* (see index 0 above)
;; (q< |text| ui:*edit*)
;; (setf qml:*root-item* nil) ; (2) reset
;;
;; N.B. we need SETF (instead of LET) because of the global var and threads
;; (QRUN* is used internally here)
;;
(let ((parent (or *root-item* (root-item)))) (let ((parent (or *root-item* (root-item))))
(when (and parent (/= 0 (qt-object-address parent))) (when (and parent (/= 0 (qt-object-address parent)))
(if (string= (qobject-name parent) object-name) (if (string= (qobject-name parent) object-name)
parent parent
(qfind-child parent object-name))))) (qfind-child parent object-name)))))
(defmacro with-root-item (root-item &body body)
"args: (root-item)
Say you have a Repeater QML item with multiple instances of the same
QQuickItem. The children of those QQuickItems all have the same object names,
respectively. In order to access those child items, we need to search in one
specific item of the Repeater.
(with-root-item (q! |itemAt| ui:*repeater* 0)
(q< |text| ui:*edit*))"
`(prog2
(setf qml:*root-item* ,root-item)
(progn
,@body)
(setf qml:*root-item* nil)))
(defun quick-item (item/name) (defun quick-item (item/name)
;; for internal use ;; for internal use
(cond ((stringp item/name) (cond ((stringp item/name)