Great to hear someone else is also working with ClojureScript on QML! Although a REPL is cool, what I would really like is getting the :advanced mode working. I did get some trivial examples to work with your root context manipulation trick.
However, it falls apart with "global" scripts (.pragma library), since, according to Qt docs: "Global code is run in a reduced scope. During startup, if a QML file includes an external JavaScript file with "global" code, it is executed in a scope that contains only the external file itself and the global object." After experimenting I conclude that even context properties set before loading the .qml file(s) don't exist (I get a "global is not defined" error). Using "this" doesn't work either and apparently its value is neither the root context nor the root object of the script. I am at a loss here. Maybe the solution involves finding out what actually exists when "global" code is loaded (is the "global object" the root context? If not, what is it then?). If nothing else helps, maybe the script needs to be loaded and evaluated from C++ with engine.evaluate? perjantai, 4. heinäkuuta 2014 3.34.44 UTC+3 Aaron Craelius kirjoitti: > Hi all, > > I have been trying to get Clojurescript working with QML and want to report > how I have gotten a QML-based Clojurescript REPL working. > > Although some minimal working examples have been posted - > https://github.com/fehrenbach/qmcljs and > https://github.com/halgari/qt_with_cljs - it has become evident that getting > a working REPL is significantly more difficult. > > I initially got a somewhat functional REPL working by porting Weasel and > using Qt 5.3's Websockets: > https://github.com/aaronc/weasel/blob/master/src/cljs/weasel/repl.cljs. > Because of QML's unusual behavior with respect to scoping - the root cannot > be modified and the value of this for the file from which Clojurescript was > loaded cannot be modified after loading the file. As a result, QML usually > throws type errors when you try to def most things from the REPL. > > My solution to the scoping issue is somewhat of a hack and currently only > works with :whitespace optimizations. One nice thing about the hack, however, > is that it does allow Clojurescript to modify QML's global scope. Therefore > any namespaces defined by Clojurescript will be available to the whole Qml > environment. This may or may not be desirable, but it is the only way I've > been able to get a REPL working and I would like to ^:export at least some > Clojurescript var's globally to QML. > > Anyway, this is what I had to do: > > in C++: > QQmlApplicationEngine engine; > QObject* global = new QObject(); > // reset the root context to my context object > engine.rootContext()->setContextObject(global); > // and expose it globally as "global" > engine.rootContext()->setContextProperty("global", global); > > The following preamble is required to the generated javascript: > var goog = goog || {}; // make sure the goog object is created > // before base.js is loaded > goog.global = global; // set goog.global to point to my context property > // which is actually the QML root context! > global.goog = goog; // make sure goog is defined in my global context. > > > And line 47 in > https://github.com/google/closure-library/blob/master/closure/goog/base.js, > needs to be changed to: > goog.global = goog.global || this; // only redefine goog.global if it doesn't > exist > > I should mention that :simple optimizations almost work, but there are issues > if you want to modify an already defined namespace because the Closure > compiler converts a lot of google.provide("my_ns") into simply var my_ns = > {}. This turns out to be an issue if you want to modify that ns from the REPL > because of scoping issues. The good news is that, it looks like :simple work > if you don't need a full REPL and will only expose the ^:export'ed vars. > :advanced mode works partially is probably a matter of declaring the correct > externs. > > Would any of the Clojurescript maintainers want to comment on this > approach... and on the possibility of patching base.js and adding a :qml > compilation :target? -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
