[Interest] Accessing the raw value of QQmlScriptString (QDeclarativeScriptString::script)

Jan Kundrát jkt at flaska.net
Wed Sep 4 16:06:26 CEST 2013


Hi.
I'm porting one piece of software from <QtDeclarative> to Qt5's native 
<QtQml> module. One obstacle which I've hit so far is the lack of access to 
the raw, unprocessed "script text" from QQmlScriptString which was formerly 
possible via QDeclarativeScriptString::script. Here is how I use this.

At one side of an application, there's a module which reads description of 
"supported objects". These files are written in QML, using custom objects 
(so that you cannot instantiate e.g. a Rectangle) -- this is how a sample 
file might look like:

frobzinator.qml:

Device {
  width: 120
  height: 10
  name: "Frobzinator"

  Property {
    name: "price"
    type: int
  }

  Property {
    name: "procured"
    type: QDateTime
  }

  validator: price < 666 && procured >= 2012
}

When our application reads this file, it registers the "Frobzinator" 
component to be available to the users. They can add new "Frobzinators" to 
some canvas, and our app knows that it should let them edit two custom 
properties, the "price" and "procured". When users have finished editing, 
the app should check that the price is less than 666 units and that the 
item was not "procured" before 2012.

As it is right now, the application is using QtDeclarative for parsing the 
definitions of the allowed data types. An internal data structure is 
created and the actual string "price < 666 && procured >= 2012" is stored 
for later use. The GUI of this application is based on QGraphicsScene, and 
when it is time to validate the object properties, a throwaway 
QDeclarativeExpression is created, we feed its context object actual data 
via setContextProperty() calls, and in the end evaluate the expression. 
Now, this specific case describes a pretty trivial concept which is 
expressible by simple boundary checking, but we want to support more 
complicated expressions including function calls to some utility JS 
library.

The important feature of this design is that the actual validator script is 
passed as plaintext, not as an already compiled JS, and that the 
user-created objects have nothing to do with QML. I suspect that this 
desing might even be required (the original context objects from 
frobzinator.qml are long gone when we get around to calling these 
validators) and it's also, IMHO, a good practice to introduce a clear 
separation between the "let's parse the supported data formats" and "let's 
work with the user-provided data" phases without introducing 
interdependencies in there. In Qt4 and Qt5's QtDeclarative compatibility 
module, this was easy to do thanks to QDeclarativeScriptString::script(). 
However, this has moved into the PIMPL in Qt5's QtQml.

Can I somehow access (and reuse in an QQmlExpression later) the raw, 
unprocessed script value in Qt5's QtQML? Why was the script() method 
removed in Qt5, and would you object to a patch adding it back? Is that 
feasible, technically?

With kind regards,
Jan

-- 
Trojitá, a fast Qt IMAP e-mail client -- http://trojita.flaska.net/



More information about the Interest mailing list