Re: [Development] Problems with QmlEngine and importPath
Hi, Out of interest, what is the content of your qmldir file? Is your qmlRegisterTypes() function being called at all? If so, does your plugin attempt to install any types into a restricted namespace (eg, QtQuick), or into multiple namespaces? I assume that it isn't, though - are any warnings or errors emitted from QML regarding import type namespace and import path mismatch, or similar? I assume you're on Windows, since you mention that you're using Angle. I don't have a Windows box I can test on at the moment, unfortunately. We did make the QML module import rules more strict, recently (however we also intended to keep current import semantics mostly working, to support legacy modules). Matt (cc'd) should be able to give more information. Cheers, Chris. From: development-bounces+christopher.adams=nokia@qt-project.org [development-bounces+christopher.adams=nokia@qt-project.org] on behalf of ext Wehmer, Matthias [matthias.weh...@draeger.com] Sent: Wednesday, 29 August 2012 8:37 PM To: development@qt-project.org Subject: [Development] Problems with QmlEngine and importPath Hi everybody, we’ve tried several other things now and still don’t have a clue, what is going on. Does anyone else have any further suggestions or is it indeed a bug that should be reported? Greetings Matthias -- Message: 4 Date: Tue, 28 Aug 2012 09:42:58 +0200 From: Wehmer, Matthias matthias.weh...@draeger.com Subject: [Development] Problems with QmlEngine and importPath To: development@qt-project.org development@qt-project.org Message-ID: d0c7f8994cdd784c849786cfdbe5a92804443d7...@cdecluexmbx03.corp.draeger.global Content-Type: text/plain; charset=us-ascii Hi everybody, we are currently suffering from the following problem: We fail to change the default directory for our custom qml plugins, that we have written in C++, and that we want to import (e.g. via import custom_plugin 1.0). That is the only directory our QML applications find the plugins is in the default import directory from the Qt5 directory. What is also strange is that the Qt Creator recognizes our plugin (i.e. the syntax highlighting works) in an arbitrary directory as long as the QML_IMPORT_PATH is set. We are using Qt5 with the angle project and the Qt Creator. That is what we've tried so far: 1. changing the QML_IMPORT_PATH: although this results in syntax highlighting in the Qt Creator, our application still doesn't find the plugins 2. using QmlEngine::addImportPath( dest ) : the path is in the importPathList now, we've checked that, but the plugins can't be found anyway 3. varying the qmldir files: doesn't work either Is this a known problem or is there an error in our application? Thank you in advance for your help. Greetings Matthias (i.e. the syntax highlighting works) in an arbitrary directory as long as the QML_IMPORT_PATH is set. --- This communication contains confidential information. If you are not the intended recipient please return this email to the sender and delete it from your records. Diese Nachricht enthaelt vertrauliche Informationen. Sollten Sie nicht der beabsichtigte Empfaenger dieser E-mail sein, senden Sie bitte diese an den Absender zurueck und loeschen Sie die E-mail aus Ihrem System. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Porting code from QScriptEngine (Qt4) to QJSEngine (Qt5)
Hi Andrea, My response doesn't relate to EnvJs in particular, although it may be relevant. In general, support for JavaScript in QML is still lacking (examples: instanceof doesn't work properly, due to the dichotomy between C++ inheritance and JS prototypical inheritance and constructor functions; we don't allow modification of the evaluation context of a script import; etc) and this is probably going to be one of the focuses of QtDeclarative development for 5.1. Most of those improvements are, however, out of scope for 5.0 due to time limitations. You can do something like: // main.qml Import QtQuick 2.0 Import Compat.js as JS Item { Component.onCompleted: console.log(JS.someFunction()); } // Compat.js Var Window = { test: 42 }; Qt.include(thirdParty.js); // thirdParty.js Function someFunction() { Return Window.test; } When the main.qml is run with qmlscene, we see 42 printed out as expected. In this way, third party JavaScript libraries can be made to work, with some limitations (as described previously). Michael Brasser has written some documentation about the limitations of the JavaScript environment in QML, see http://qt.gitorious.org/qt/qtdeclarative/blobs/master/src/qml/doc/src/javascript/hostenvironment.qdoc for more information. Cheers, Chris. -Original Message- From: development-bounces+christopher.adams=nokia.com@qt- project.org [mailto:development- bounces+christopher.adams=nokia@qt-project.org] On Behalf Of ext a.gra...@gmail.com Sent: Monday, June 25, 2012 5:14 PM To: Stephen Kelly Cc: development@qt-project.org Subject: Re: [Development] Porting code from QScriptEngine (Qt4) to QJSEngine (Qt5) Hi, On 21 June 2012 17:18, Stephen Kelly stephen.ke...@kdab.com wrote: On Thursday, June 21, 2012 15:33:19 a.gra...@gmail.com wrote: I've started porting some code from QScriptEngine to QJSEngine, but there are some missing parts I don't know how to implement. My understanding is that QJS* is not a replacement for QScriptEngine: http://thread.gmane.org/gmane.comp.lib.qt.devel/4185 There's nothing for you to port to yet. Maybe there will be later in Qt 5 development. I've just read all the thread, maybe it's better if I provide more details about what I'm doing. My current task is experimenting the compatibility of Qt5/QML JavaScript engine with the most popular JavaScript libraries (for example: jQuery, BackBoneJs, etc...). All these libraries need browser objects like window, document etc... to work properly. I found the EnvJs library and this useful blog article written by Kent Hansen http://labs.qt.nokia.com/2011/03/10/say-hello-to-envjs-for-qtscript/ the only problem is that he doesn't provide a complete (ready to be built) code example and he probably tested this on Qt4 (while I have to use Qt5), so I wrote a Qt5 example from scratch, trying to follow the article advices, but it's not working. I've tried to use both QtScriptEngine and QJSEngine but it doesn't work. Basically: 1) I load the env.js content and I evaluate it: qse.evaluate(js, js_errors.txt); 2) I call the initializeEnvjsNatives(qse); 3) from my main.qml I import the env.js file (I should not import it since I've already evaluated it with qse.evaluate() right? Anyway it doesn't work in both ways... import env.js as EnvJs 4) I try to use it in this way: console.log(document:, EnvJs.document); EnvJs.document.write(pHello, JavaScript in QtScript!/p); and this is the error I always get: document: undefined file:///home/andrea/Documents/EnvjsTest/qml/EnvjsTest/main.qml:24: TypeError: Cannot call method 'write' of undefined If it can be useful for you to understand better, I think I can provide the complete source code (it's just a basic example, but at least it will save you lot of time if you want to give it a try). Best regards, -- Andrea Grandi - Nokia-DXM/Tampere / Qt Ambassador Ubuntu Member: https://launchpad.net/~andreagrandi website: http://www.andreagrandi.it ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Documentation Extras (Was: On QML, ownership, QObject-trees and QSharedPointer)
Hi Sivan, Hi All, Following the rather interesting discussion that started by Rene[0] , I've summarized the bits I believed to be important for others seeking the same information as he did, and put it on the wiki[1]. I've also created a new category on the wiki main page, dubbed as 'Documentation Extra'. I think this sort of brief, conclusion and instruction only docs might be exactly what those developers who cannot allow themselves hours of reading and are in midst of implementation, seek. If we accumulate those based on mailing list discussion as in this example, we'd have a solid base to augment and perfect the docs with, a'la In the hurry style. Christopher, Kent: Could you kindly please review my summary to make sure is indeed correct, particularly- note which of the listed here[2] are indeed only available in QtQuick2 part of Qt5? Many thanks, -Sivan [0]: http://lists.qt-project.org/pipermail/development/2012- May/004049.html [1]: http://qt-project.org/wiki/SharedPointersAndQmlOwnership [2] http://qt-project.org/wiki/property-var It mostly looks fine to me. The JS Object to / from QVariantMap conversion isn't new to QtQuick 2.0, and QListint was supported in QtQuick 1.0 (but in a much slower form). But in general the summary is correct, I believe. However, as mentioned in my initial response to Rene, we are overhauling the documentation at the moment, so hopefully it manages to capture all of the required information in a simple and accessible manner. Wiki pages have a tendency to grow stale, unfortunately. Cheers, Chris. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] On QML, ownership, QObject-trees and QSharedPointer
Hi, In QtQuick 2.0 (ie, Qt 5.0), we are thinking about using property var more often in the implementation (eg, of qobject-derived-type properties) to avoid some of those edge-cases, and providing more consistent (and useful) referencing semantics. Can you say what 'var' is and why it would help? In QtQuick 1.x, you could not define a JavaScript var-type property in a QML item. The closest thing provided was property variant which, internally, is a QVariant. Assigning a JavaScript object to that property would result in it being converted to a QVariantMap. Accessing that property from JS would result in that QVariantMap being converted back into a JS object. You could not store a JS function reference, or any other special JS value in a property variant property (eg, null, undefined). In QtQuick 2.0, we deprecated property variant and added property var. Internally, property var properties are JS values. Thus, you can store anything created in JS, including JS function references. This allows greater dynamicity and flexibility. Only when you access that property from C++ (via QObject::property() or QQmlProperty::read()) will it be converted to a QVariant (following the same conversion rules as for any other JS value to QVariant conversion). If we were to implement property variant as a synonym for property var in QtQuick 2.0, the code base would be simplified, and the referencing semantics made more consistent (more on this later). I haven't benchmarked the performance impact of such a change, yet, however. Does what you say about handling qobject-derived-type properties have anything to do with this: https://codereview.qt-project.org/#change,13006 https://codereview.qt-project.org/#change,13007 or do you have something else in mind? When I said qobject-derived-type I should have said User-defined (via custom components) QML types. Eg, if you have a file named MyButton.qml, you can use MyButton as a type. It is a QQuickItem-derived type (and thus a QObject-derived type). The problem is that currently, the ownership semantics are (in my opinion) quite strange. In particular: import QtQuick 2.0 Item { id: root property MyButton buttonOne: MyButton { ... } property MyButton buttonTwo property variant buttonThree: MyButton { ... } property variant buttonFour property var buttonFive: MyButton { ... } property var buttonSix function generateButton() { var c = Qt.createComponent(MyButton.qml); var o = c.createObject(null); // no explicit parent return o; } function generateButtons() { buttonTwo = generateButton(); buttonFour = generateButton(); buttonSix = generateButton(); } Component.onCompleted: { generateButtons(); gc(); gc(); gc(); gc(); } } That example will cause button two and four to be collected / destroyed via garbage collection. Because the generated buttons had no explicit parent given, they have JS ownership and will be collected if no JS references to them exist. QVariant-backed property types (like MyButton and variant) don't store JS values (and thus don't cause JS references to exist) and thus buttons two and four will be collected. The only reason why buttonOne and buttonThree aren't collected is that we explicitly set the parent of the RHS item, during instantiation (in the VME, during CreateSimpleObject). To me, it seems strange that root is the parent of buttonOne and buttonThree, but not the parent of buttonTwo or buttonFour (given that the only real difference is declaration vs assignment), and it is certainly strange that even though buttonTwo and buttonFour reference their associated values, the gc will still collect them. Note that buttons five and six are not collected, because they are JS values (which will prevent the gc from collecting what they reference). See QTBUG-24767 for more information. There is a change which fixes the referencing strangeness, but it may have a performance impact during gc cycles, which we are currently evaluating. Cheers, Chris. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] On QML, ownership, QObject-trees and QSharedPointer
Hi Rene, I certainly agree that constructive discussion about the QML language and ways that it could be improved are important. You raise a lot of important points, some of which will be addressed in Qt5.0, some of which we still need to consider how to fix, and what priority they should be, for future minor releases of Qt. More comments inline (some sections removed for brevity). OWNERSHIP... These are the ownership universes (unless I'm mistaken): 1) Objects created in C++ owned via the QObject parent/child tree e.g.: new MyGizmo. 2) Objects created in C++ owned via the QSharedPointer system, e.g.: QSharedPointer (new MyGizmo). 3) Objects created by QDeclarativeEngine or Javascript owned by the engine, e.g.: MyGizmo { ... properties ... } Question: How can we expose objects governed by QSharedPointer to QML safely? I *can* guarantee the lifecycle beyond the life of my QDeclarativeEngine. Currently, QML isn't aware of QSharedPointer and friends, but internally uses its own guard-types to react to QObject deletion. If you want to ensure that the engine won't delete the QObject you pass in, you need to explicitly set the ownership of the QObject to CppOwnership (there's a QQmlEngine function to do so). Alternatively, if the QObject has a parent (ownership parent) set, the engine won't delete it. These are the ways to transfer values/references from C++ to QML (let's ignore the other way around for now): A) By calling QDeclarative::setRootContext (ownership not transferred: http://qt-project.org/doc/qt- 4.8/qdeclarativecontext.html#setContextProperty). B) By calling QObject::setProperty on the instantiated component (ownership?) C) By QML calling a method on a C++ object and getting a response (ownership IS transferred to QML. In the docs somewhere.) D) By QML accessing a Q_PROPERTY on a C++ object (ownership?). Now, A+B lend themselves badly as mechanisms to expose subobjects, but makes it easy to specify ownership via QDeclarativeEngine::setObjectOwnership. Conversely C+D are better at exposing subobjects or related collections (in QML... myProperty: myGizmo.findAllTimelineEvents() ), but I don't see how I can specify ownership in a QML-agnostic way (C++ models should not know about QML!) I don't understand your last point. What do you mean in a QML-agnostic way? The QML engine respects normal QObject parenting. You are correct about (c) by the way: if the QObject returned from a Q_INVOKABLE function to JS does not have CppOwnership explicitly set, it will become JavaScriptOwnership owned. To avoid that, you can explicitly set the ownership semantic prior to returning it. With (b) ownership is not transferred. However, it should be noted that if you define a QObject-derived-type property in QML with its value declared (ie, via property Item propName: Item { id: child }) that property's QObject value will be owned by the object with the propName property. But this isn't directly related to interacting with QML from C++, and so is probably unrelated to what you are talking about. Question: What happens to ownership in each of these transfers? To summarise: a) no ownership change b) no ownership change c) ownership change if ownership semantics were not previously explicitly set d) no ownership change TYPESYSTEM... Then there is the issue of what type is associated with the object. This is relevant when specifying properties in QML. I believe that a major source of confusion comes from the notion that there are three type systems involved: 1) The traditional Qt/C++ moc/compiler types (perhaps QObjects, perhaps declared Q_DECLARE_METATYPE to make QVariant understand them) 2) The types that the Javascript engine knows (Object, Function, Number, String etc.) 3) The types that the QML engine understands (http://doc-snapshot.qt- project.org/4.8/qdeclarativebasictypes.html plus those registered with qmlRegisterType). QVariants can be used too. Question: Are there 2 or 3 typesystems? I guess it depends on how you define the term. There are only two property types that the QML engine understands: JavaScript vars, and QVariant properties. It just happens that it builds type information from the loaded component set, and enforces type safety when assigning to properties of those types (which is why you cannot assign an Item {} to a property of type Rectangle). But internally, all properties are stored as either QVariants or JavaScript vars. I assume that each time a value crosses a boundary between from C++ = QML = Javascript an automatic conversion takes place. This conversion is probably the root of all evils, since a lot can happen with pointer references being smashed to either some form of null (as in unsuccessful C++ to QML assignment via (A) or (B) above) or undefined (like when a javascript expression tries to access a QML Component property) depending on factors not quite clear to me. Question:
Re: [Development] V8 on iOS
Hi, At this point, I'm either looking for an alternative to V8 This is more of an follow-up question for the list than a reply: QtDeclarative includes the V4 javascript interpreter that (as far as I know) can handle simple javascript expressions. How far can you get with V4 only? Could using V4 only be a good way of bootstrapping a V8-challenged platform? Currently, v4 is quite limited in the sort of expressions that it can evaluate. It would be possible to improve v4 to handle a greater range of expressions (eg, perhaps being able to handle JS function calls, so long as the function being called is itself v4-able) which would be beneficial for everyone. However it is simply not possible to improve v4 to handle all expressions, and thus some form of naïve JS interpreter (which doesn't do JIT compilation or any form of on-stack code generation) would be required in order to evaluate complex bindings, complex signal handlers, and so on, if iOS does indeed require noexec stack etc. In summary: not very far, with v4 only. So the question is: could the dependence on v8 within QtDeclarative be changed, so that a naive JS implementation could be used instead, if v8 is not available on that platform? Theoretically: yes. Practically: no. We gain a lot of advantages from tight integration with v8 (and indeed, we want to increase the tightness of that integration in order to improve performance further, eg, caching C++-side property resolution etc) and the performance of a naïve interpreter would probably be a showstopper anyway (even if v4 was improved to handle more cases than it does currently). Also, it's a huge amount of work to #ifdef out all of the v8 integration within QtQml and QtQuick currently (and even more work to use hypothetical JS-backend-abstracting APIs provided by QtJsBackend as a true JS abstraction, which would also have massive performance implications). Cheers, Chris. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML: grouping property changes for a single callback invocation
Hi Alberto, Firstly, this is a really interesting topic, so thanks for bringing it up, and even more thanks for offering to help investigate and implement changes! Secondly, this problem is one that we have considered before, and the ideal solution is probably some binding is dirty flag, combined with pull properties when required mechanism (rather than the current always re-evaluate bindings on change propagation method). But that solution is a lot of work, so your suggestion may indeed be a very nice half-way-there compromise. But it isn't without its risks, so more comments in-line. It's pretty much as you described. With the slight addendum that what you're asking for is probably not possible (in the general case). X and Y are independent variables, one may change without the other. So the code can't just wait for a signal which may or may not ever come. If you have a solution for this problem, I'm all ears :) . I've been giving it some thoughts, but my idea is very rough at the moment. It's about queuing all the invocations of property signals (and property bindings) and fire them in an idle callback to be invoked later. So, supposing that you have this QML code: === property int width: x + sizeX onXChanged: functionA() === instead of connecting the onXChanged() signal to function A and to the re- evaluation of the width property, you would connect to a slot that simply does something like this: { listOfChangedProperties.append(x); /* next line sets up an idle event (QTimer with time set to 0, * maybe), if one is not set already */ setupIdleEvent(); } Then, when the idle callback will be invoked, it will go through listOfChangedProperties and for each of them invoke the slots connected to them, and recompute the values of other properties depending on them, each time marking the dependent slot/property as processed, in order to avoid processing it more than once during the same idle invocation. One important note is that this sort of signal coalescing does have performance implications. Also, we have no guarantees of when the idle callback will be invoked, which could be problematic (more on this later). Also note that the LHS property will change as a result of the slot invocation in the idle callback, so in order for this suggestion to work properly, you'd need to enable cascade-updates of bindings (ie, current behavior) during that callback (since doing the coalescing and setupIdleEvent() for that change would almost guarantee that the change wouldn't be calculated until the next 16 ms timeslice - more on this later). This would also mean that if both x and sizeX change before the idle callback is invoked, the width property expression would have to be computed only once. The savings from this would be substantial only if the average application includes a significant number of complex bindings, and if multiple properties within the binding change simultaneously. If the cost of doing the coalescing in every case outweighs the benefit of avoiding recalculating both in a minority case, then we should not do this. However, I suspect that complex bindings are quite common, and I'm certain that the cost of doing even one redundant binding evaluation would outweigh the cost of coalescing, so I'm fairly certain that this would turn out to be a net-win. But it needs to be benchmarked thoroughly. I didn't have a look at QDeclarative source code yet, so I'm all ears for your opinion (and hints, in case I want to spend some time to investigate this possibility). The major problem I have with this suggestion is the use of the idle-timer. The problem is this: for a 60fps Velvet application, you have 16 ms to do the processing of all animations, binding updates, signal handlers, view delegate creation and so forth, then synchronise with the render thread. By depending on the idle callback, and doing all bindings updates in there, you run the risk of updates not being propagated during the critical time slice, resulting in unsmooth animations, etc. One possibility would be to use the unified timer (triggered by vsync) to trigger coalescing and then evaluation, perhaps with some form of co-operative yield between individual binding evaluations to avoid skipping frames (see, for example, the threaded instantiation logic of the asynchronous loader). I would be very interested in seeing a prototype of this solution (even with just using an idle callback, as a first iteration) that we could benchmark and discuss more thoroughly. I'd also be interested to hear what Aaron Kennedy, Kent Hansen and Michael Brasser think about the idea, as they would have a better grasp of the possible problems that could arise from this sort of change, than I do. Cheers, Chris. ___ Development mailing list Development@qt-project.org