extend QSELECT / QSEL to work with QML items; revision of property dialog; small revisions;

This commit is contained in:
polos 2017-02-16 17:24:08 +01:00
parent 2b777c6e8c
commit 2f67ce73b4
23 changed files with 139 additions and 74 deletions

View file

@ -1,5 +1,4 @@
#include "qml_lisp.h" #include "qml_lisp.h"
#include <eql_fun.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -106,9 +105,4 @@ QVariant Lisp::apply(const QJSValue& caller_or_function,
arguments = function_or_arguments.toVariant().value<QVariantList>(); } arguments = function_or_arguments.toVariant().value<QVariantList>(); }
return qmlApply(caller, function, arguments); } return qmlApply(caller, function, arguments); }
void PaintedItem::paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -3,6 +3,7 @@
#include <QtQml> #include <QtQml>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <eql_fun.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#define LIB_EXPORT __declspec(dllexport) #define LIB_EXPORT __declspec(dllexport)
@ -48,7 +49,10 @@ class PaintedItem : public QQuickPaintedItem {
public: public:
PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {} PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {}
void paint(QPainter*); void paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -10,5 +10,4 @@
(when (stringp item) (when (stringp item)
(setf item (qml:find-quick-item item))) (setf item (qml:find-quick-item item)))
(funcall (sym :show :properties) (funcall (sym :show :properties)
(or item qml:*caller*) (or item qml:*caller*)))
t)) ; all instance properties (for QML)

View file

@ -10,3 +10,11 @@ RUN
=== ===
Please run it from this directory. Please run it from this directory.
HELP
====
To list all properties of the 'ListView', do:
(show-properties-dialog (root-item)) ; see "properties.lisp"

View file

@ -1,5 +1,4 @@
#include "qml_lisp.h" #include "qml_lisp.h"
#include <eql_fun.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -106,9 +105,4 @@ QVariant Lisp::apply(const QJSValue& caller_or_function,
arguments = function_or_arguments.toVariant().value<QVariantList>(); } arguments = function_or_arguments.toVariant().value<QVariantList>(); }
return qmlApply(caller, function, arguments); } return qmlApply(caller, function, arguments); }
void PaintedItem::paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -3,6 +3,7 @@
#include <QtQml> #include <QtQml>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <eql_fun.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#define LIB_EXPORT __declspec(dllexport) #define LIB_EXPORT __declspec(dllexport)
@ -48,7 +49,10 @@ class PaintedItem : public QQuickPaintedItem {
public: public:
PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {} PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {}
void paint(QPainter*); void paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -10,5 +10,4 @@
(when (stringp item) (when (stringp item)
(setf item (qml:find-quick-item item))) (setf item (qml:find-quick-item item)))
(funcall (sym :show :properties) (funcall (sym :show :properties)
(or item qml:*caller*) (or item qml:*caller*)))
t)) ; all instance properties (for QML)

View file

@ -2,7 +2,7 @@ import QtQuick 2.0
import EQL5 1.0 import EQL5 1.0
ListView { ListView {
x: 5; y: 5; width: 200; height: 250 width: 200; height: 250
model: myModel model: myModel
delegate: Text { text: "animal: <b>" + kind + "</b>, " + size } delegate: Text { text: "animal: <b>" + kind + "</b>, " + size }

View file

@ -2,7 +2,7 @@ import QtQuick 2.0
import EQL5 1.0 import EQL5 1.0
ListView { ListView {
x: 5; y: 5; width: 150; height: 250 width: 150; height: 250
model: myModel model: myModel
delegate: Rectangle { delegate: Rectangle {

View file

@ -39,4 +39,4 @@ Examples:
(qproperties* (qml:find-quick-item "left")) (qproperties* (qml:find-quick-item "left"))
(show-properties-dialog (qml:find-quick-item "left")) (show-properties-dialog "left") ; see "properties.lisp"

View file

@ -1,5 +1,4 @@
#include "qml_lisp.h" #include "qml_lisp.h"
#include <eql_fun.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -106,9 +105,4 @@ QVariant Lisp::apply(const QJSValue& caller_or_function,
arguments = function_or_arguments.toVariant().value<QVariantList>(); } arguments = function_or_arguments.toVariant().value<QVariantList>(); }
return qmlApply(caller, function, arguments); } return qmlApply(caller, function, arguments); }
void PaintedItem::paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -3,6 +3,7 @@
#include <QtQml> #include <QtQml>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <eql_fun.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#define LIB_EXPORT __declspec(dllexport) #define LIB_EXPORT __declspec(dllexport)
@ -48,7 +49,10 @@ class PaintedItem : public QQuickPaintedItem {
public: public:
PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {} PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {}
void paint(QPainter*); void paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -10,5 +10,4 @@
(when (stringp item) (when (stringp item)
(setf item (qml:find-quick-item item))) (setf item (qml:find-quick-item item)))
(funcall (sym :show :properties) (funcall (sym :show :properties)
(or item qml:*caller*) (or item qml:*caller*)))
t)) ; all instance properties (for QML)

View file

@ -74,10 +74,12 @@ can't be inspected using QPROPERTIES (only the generic ones).
To list all properties (including user defined ones), use QPROPERTIES* instead. To list all properties (including user defined ones), use QPROPERTIES* instead.
Example: Examples:
(qproperties* (qml:find-quick-item "label")) (qproperties* (qml:find-quick-item "label"))
(show-properties-dialog "label") ; see "properties.lisp
TIP TIP
=== ===

View file

@ -1,5 +1,4 @@
#include "qml_lisp.h" #include "qml_lisp.h"
#include <eql_fun.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -106,9 +105,4 @@ QVariant Lisp::apply(const QJSValue& caller_or_function,
arguments = function_or_arguments.toVariant().value<QVariantList>(); } arguments = function_or_arguments.toVariant().value<QVariantList>(); }
return qmlApply(caller, function, arguments); } return qmlApply(caller, function, arguments); }
void PaintedItem::paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -3,6 +3,7 @@
#include <QtQml> #include <QtQml>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <eql_fun.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#define LIB_EXPORT __declspec(dllexport) #define LIB_EXPORT __declspec(dllexport)
@ -48,7 +49,10 @@ class PaintedItem : public QQuickPaintedItem {
public: public:
PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {} PaintedItem(QQuickItem* parent = 0) : QQuickPaintedItem(parent) {}
void paint(QPainter*); void paint(QPainter* painter) {
eql_fun("qml:paint",
Q_ARG(QQuickPaintedItem*, this),
Q_ARG(QPainter*, painter)); }
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View file

@ -10,5 +10,4 @@
(when (stringp item) (when (stringp item)
(setf item (qml:find-quick-item item))) (setf item (qml:find-quick-item item)))
(funcall (sym :show :properties) (funcall (sym :show :properties)
(or item qml:*caller*) (or item qml:*caller*)))
t)) ; all instance properties (for QML)

View file

@ -9,7 +9,7 @@ Item {
// Please note: // Please note:
// //
// * to call lisp functions, use either Lisp.call() or Lisp.apply(); // * to call Lisp functions, use either Lisp.call() or Lisp.apply();
// use JS arrays for lists (can be nested); // use JS arrays for lists (can be nested);
// //
// * the only limit to Lisp.call() is the number of arguments (max. 16); // * the only limit to Lisp.call() is the number of arguments (max. 16);
@ -22,7 +22,7 @@ Item {
// Lisp.call() or Lisp.apply(); it can then be accessed in Lisp via qml:*caller*; // Lisp.call() or Lisp.apply(); it can then be accessed in Lisp via qml:*caller*;
// (1) call CL function // (1) call CL function
console.log(Lisp.call("format", false, "~R", 123)) console.log(Lisp.call("format", null, "~R", 123))
// (2) call EQL function // (2) call EQL function
Lisp.call("qmsg", "hello from QML") Lisp.call("qmsg", "hello from QML")

View file

@ -15,7 +15,8 @@
*view* *view*
*depth* *depth*
*label* *label*
*instance-properties*) *instance-properties*
*select*)
(defvar *font* (format nil "font-family: ~A; font-size: ~Apt;" (defvar *font* (format nil "font-family: ~A; font-size: ~Apt;"
#+darwin "Monaco" #+darwin 12 #+darwin "Monaco" #+darwin 12
@ -33,7 +34,8 @@
(! "resize" *main* '(650 500)) (! "resize" *main* '(650 500))
(qset-color *view* |QPalette.Base| "lightyellow") (qset-color *view* |QPalette.Base| "lightyellow")
(qconnect *depth* "valueChanged(int)" 'update) (qconnect *depth* "valueChanged(int)" 'update)
(qconnect *instance-properties* "toggled(bool)" 'all-instance-properties)) (qconnect *instance-properties* "toggled(bool)" 'all-instance-properties)
(qconnect *select* "clicked()" 'selected))
(defun update (depth) (defun update (depth)
(! "setText" *label* (! "setText" *label*
@ -51,11 +53,13 @@
(|setEnabled| w (not checked))) (|setEnabled| w (not checked)))
(show)) (show))
(defun show (&optional object qml) (defun selected ()
(when qml (qselect (lambda (object) (show (symbol-value (find-symbol (symbol-name :*q*) :qsel))))))
(! "setChecked" *instance-properties* t))
(defun show (&optional object)
(when object (when object
(setf *object* object) (setf *object* object)
(! "setChecked" *instance-properties* (! "inherits" *object* "QQuickItem")) ; for QML items
(let ((depth 1) (let ((depth 1)
(name (qt-object-name *object*))) (name (qt-object-name *object*)))
(! "setText" *label* name) (! "setText" *label* name)

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>466</width> <width>417</width>
<height>336</height> <height>357</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -48,11 +48,31 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="instance_properties"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="text"> <item>
<string>all instance properties (for QML)</string> <widget class="QCheckBox" name="instance_properties">
</property> <property name="sizePolicy">
</widget> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>all instance properties (for QML)</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="select">
<property name="toolTip">
<string>Select QWidget or QQuickItem</string>
</property>
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>

View file

@ -88,7 +88,7 @@ void DynObject::clearEventFilters() {
event_objects.clear(); } event_objects.clear(); }
bool DynObject::eventFilter(QObject* object, QEvent* event) { bool DynObject::eventFilter(QObject* object, QEvent* event) {
if(event_filters && object->isWidgetType()) { if(event_filters && (object->isWidgetType() || object->isWindowType())) {
for(int i = 0; i < event_objects.size(); ++i) { for(int i = 0; i < event_objects.size(); ++i) {
if(!event_objects.at(i) || (object == event_objects.at(i))) { if(!event_objects.at(i) || (object == event_objects.at(i))) {
if(event->type() == event_types.at(i)) { if(event->type() == event_types.at(i)) {

View file

@ -7,7 +7,7 @@
#include <QTimer> #include <QTimer>
#include <QStringList> #include <QStringList>
const char EQL::version[] = "17.2.6"; // Feb 2017 const char EQL::version[] = "17.2.7"; // Feb 2017
extern "C" void ini_EQL(cl_object); extern "C" void ini_EQL(cl_object);

View file

@ -1,7 +1,8 @@
;;; copyright (c) Polos Ruetz ;;; copyright (c) Polos Ruetz
;;; ;;;
;;; Allows to visually select (mouse click) any (child) widget. ;;; Allows to visually select (mouse click) any child widget or QML item.
;;; On selecting, the widget will be highlighted, and qsel:*q* will be set to the latest selected widget. ;;; On selecting, the widget/item will be highlighted, and qsel:*q* will be set
;;; to the latest selected widget/item.
(defpackage :qselect (defpackage :qselect
(:nicknames :qsel) (:nicknames :qsel)
@ -21,27 +22,33 @@
(in-package :qselect) (in-package :qselect)
(defvar *listen* nil)
(defvar *q* nil) (defvar *q* nil)
(defvar *on-selected* nil) (defvar *on-selected* nil)
(defvar *pos* nil)
(let ((cross-cursor (qnew "QCursor(Qt::CursorShape)" |Qt.CrossCursor|)) (let ((cross-cursor (qnew "QCursor(Qt::CursorShape)" |Qt.CrossCursor|)))
listen)
(defun object-selected (object event) (defun object-selected (object event)
(when listen (unless (zerop (qt-object-id object)) ; exclude unknown to EQL
(setf listen nil) (when *listen*
(setf *q* object) (setf *listen* nil
(setf (qt-object-unique object) (! ("toUInt" ("property" "EQL.unique") *q*))) *q* object
(indicate) *pos* (! "pos" event))
(! "restoreOverrideCursor" "QGuiApplication") (setf (qt-object-unique object)
(when *on-selected* (! ("toUInt" ("property" "EQL.unique") *q*)))
(funcall *on-selected* object)) (if (find (! "className" (! "metaObject" *q*))
t)) ; event filter '("LQuickView" "LQuickWidget") :test 'string=)
(indicate*) ; QML items
(indicate)) ; QWidgets
(! "restoreOverrideCursor" "QGuiApplication")
(when *on-selected*
(funcall *on-selected* object))
t))) ; event filter
(defun select-mode () (defun select-mode ()
(if (! "topLevelWidgets" "QApplication") (setf *listen* t)
(progn (! "setOverrideCursor" "QGuiApplication" cross-cursor)))
(setf listen t)
(! "setOverrideCursor" "QGuiApplication" cross-cursor)) ;; for QWidgets
(qmsg (tr "Please create widgets first.")))))
(defun indicate () (defun indicate ()
(let ((object *q*)) (let ((object *q*))
@ -93,3 +100,39 @@
(qlet ((painter "QPainter(QPixmap*)" dark)) (qlet ((painter "QPainter(QPixmap*)" dark))
(! "drawPixmap" painter rect pixmap rect)) (! "drawPixmap" painter rect pixmap rect))
dark)) dark))
;; for QML
(defun child (item)
(let* ((pos (! "mapFromScene" item *pos*))
(child* (! "childAt" item (first pos) (second pos))))
(if (qnull child*)
item
(child child*))))
(defun indicate* ()
(let ((root (! "rootObject" *q*)))
(indicate-start* *q* (child root))))
(defun indicate-start* (parent child)
(setf *q* child)
(let ((indicate (qnew "QLabel(QWidget*,Qt::WindowFlags)" nil |Qt.WindowStaysOnTopHint|)))
(! "move" indicate (nbutlast (! "frameGeometry" parent) 2))
(! "resize" indicate (list (! "width" parent)
(! "height" parent)))
(let* ((pix (if (! "isWidgetType" parent)
(! "grab" parent) ; QQuickWidget
(! "fromImage" "QPixmap" (! "grabWindow" parent)))) ; QQuickView
(dark (to-dark pix)))
(! "setPixmap" indicate (set-highlight* indicate pix dark child)))
(qlater (lambda () (! "show" indicate)))
(qsingle-shot 500 (lambda () (qdel indicate)))))
(defun highlight* (child)
(! "mapRectToScene" child (list 0 0 (! "width" child) (! "height" child))))
(defun set-highlight* (indicate pixmap dark child)
(let ((rect (highlight* child)))
(qlet ((painter "QPainter(QPixmap*)" dark))
(! "drawPixmap" painter rect pixmap rect))
dark))