diff --git a/Qt_EQL/tutorial/main.cpp b/Qt_EQL/tutorial/main.cpp index 5b07e6c..957ef07 100644 --- a/Qt_EQL/tutorial/main.cpp +++ b/Qt_EQL/tutorial/main.cpp @@ -11,13 +11,13 @@ int main(int argc, char* argv[]) { main->resize(600, 400); main->show(); - // we need an instance for 'define-qt-wrappers' and 'new-instance' to work; - // we pass the main widget as parent and a unique 'objectName', so we can - // find it from Lisp - - Test test(main, "test"); - EQL eql; + + // add desired Qt class instances as Lisp variables (uses 'defvar'): + + EQL::addObject(main, "eql-user:*main-widget*"); + EQL::addObject(new Test(main), "eql-user:*test*"); + EQL::eval("(in-package :eql-user)"); EQL::eval("(load \"test.lisp\")"); // will start a REPL app.processEvents(); // needed for 'qlater' in 'test.lisp' diff --git a/Qt_EQL/tutorial/test.h b/Qt_EQL/tutorial/test.h index 6db8fb5..773a17a 100644 --- a/Qt_EQL/tutorial/test.h +++ b/Qt_EQL/tutorial/test.h @@ -7,17 +7,19 @@ class Test : public QObject { Q_OBJECT public: - Test(QObject*, const QString&); + Test(QObject* = nullptr, const QString& = QString()); // define function acting as constructor (callable from Lisp) // N.B. return a vanilla Qt class (here: QObject*) known to EQL5 - Q_INVOKABLE QObject* newInstance(QObject*, const QString&); + Q_INVOKABLE QObject* newInstance(QObject* = nullptr, const QString& = QString()); public Q_SLOTS: - // you may pass any type found in '~/eql5/src/ecl_fun.cpp::toMetaArg()' + // you may pass any type found in '~/eql5/src/ecl_fun.cpp::toMetaArg()'; + // it's common practice in Qt to always pass const references (except for + // pointers, of course), as you'll find in any Qt example code QString concat(const QStringList&); - // pass Lisp data + // pass Lisp data ('cl_object' is just a pointer) void processData(cl_object); // call back to Lisp diff --git a/Qt_EQL/tutorial/test.lisp b/Qt_EQL/tutorial/test.lisp index 6939289..ac53ec5 100644 --- a/Qt_EQL/tutorial/test.lisp +++ b/Qt_EQL/tutorial/test.lisp @@ -1,11 +1,5 @@ (in-package :eql-user) -;; find main widget of app -(defvar *main-widget* (first (|topLevelWidgets.QApplication|))) - -;; find 'Test' instance by its 'objectName' -(defvar *test* (qfind-child *main-widget* "test")) - ;; the following defines generic functions for all Qt signals, ;; Qt slots and functions declared Q_INVOKABLE diff --git a/src/eql.cpp b/src/eql.cpp index 8484572..d4fc5cf 100644 --- a/src/eql.cpp +++ b/src/eql.cpp @@ -215,6 +215,16 @@ void EQL::exec(QWidget* widget, const QString& lispFile, const QString& slimeHoo if(exec_with_simple_restart) { eval("(eql::exec-with-simple-restart)"); }} +void EQL::addObject(QObject* object, const QByteArray& varName) { + int p = varName.indexOf(':'); + QByteArray pkg = (p == -1) ? "eql-user" : varName.left(p); + QByteArray var = varName.mid(varName.lastIndexOf(':') + 1); + cl_object l_symbol = cl_intern(2, + STRING_COPY(var.toUpper().constData()), + cl_find_package(STRING_COPY(pkg.toUpper().constData()))); + cl_object l_object = qt_object_from_name(LObjects::vanillaQtSuperClassName(object->metaObject()), object); + ecl_defvar(l_symbol, l_object); } + void EQL::runOnUiThread(void* function_or_closure) { const cl_env_ptr l_env = ecl_process_env(); CL_CATCH_ALL_BEGIN(l_env) { diff --git a/src/eql5/eql.h b/src/eql5/eql.h index dc21554..8b2ca57 100644 --- a/src/eql5/eql.h +++ b/src/eql5/eql.h @@ -42,6 +42,7 @@ public: static void ini(int, char**); static void ini(char**); static void eval(const char*, const EvalMode = evalMode); + static void addObject(QObject*, const QByteArray&); static EvalMode evalMode; void exec(const QStringList&);