Does Qt need a modern C++ GUI API?
-
[quote author="Daniel Eder" date="1335181849"]Regarding the "it's open source - so just contribute"-point I saw mentioned in this thread: Just because you may contribute content to a repository it does not mean somebody with a good ideas has the required abilities/time/... to do so :)[/quote]
If nobody has the required abilities and time to do so, then it won't happen. In fact, it's not about the abilities or the time. It's about the financial investment of developing and maintaining the Qt codebase. And frankly, I don't really understand what we're hoping to achieve here.
Even with open source, there's no free lunch as they say, and Qt developers are only that, paid developers. If none of the major contributing employers (Nokia for the most part, but also Digia, KDAB, Accenture, Intel...) judge it interesting to invest in a C++ API, then it's indeed unlikely to become a priority anytime soon.
It's a meritocracy where Nokia happens to be the party investing the most, but luckily, it's no longer a closed group. So if there is another company out there that wants to pay several full-time devs to work their way up to a contribution point where they are part of the decisional level of Qt, then what's stopping them? Just don't expect other companies to pay for something that has obviously been judged not a priority for them. I know it sounds a little cold, but I think that's really all there is to it. -
[quote author="c++freeloader" date="1335171302"]bq. Simply exposing the C++ interface of all QML elements won’t buy you anything, as the most important feature of Qt Quick (bindings) still can’t be handled that way
Can someone please explain why the above statement is true (or not)?[/quote]
It is true. Well, at least most of it. The thing is that normally you have an object with some property, and you can bind that object's value to another value in some overloaded method, like the paint event. This is somewhat tedious and has to be specific for every different scenario. And in QML you are isolated from all this, unless you dig into creating a custom object in C++, and this is where JS comes in handy for some wiring of properties.
That being said, there are alternatives to that in C++, and while they have their overheads, those are minimal compared to the overhead of having a running JS VM and JS execution.
One solution that comes to mind is instead of storing the value of a property, the object stores an address of a property, so binding to another object property becomes fairly simple, but in case you want a regular property you need to instantiate that type and pass it to the object, effectively binding to another object again.
You can also have a bool whether a property is set or bound, and a union that can either hold an address of a property in the case of bound or the actual property in the case of set. You can use bit packing to minimize the space used by all those bools for every property.
You can also instantiate a binder object (can even be a part of the QQApplication too) which may take any number of bindings between objects and properties in any order you want to, it will not be automatic as it currently happens in QML with JS but it is not that much of a pain too, and its overhead will once again be minimal compared to the overhead QML induces.
Last and least, as I mentioned, you can have an empty virtual method like for example bindEvent, which you overload and add your bindings there, but in this case you have to crawl up the hierarchy and shoot in the blind to connect to an object you know is there. That is why I chose this method last.
There might be other ways to do it as well, who knows, those are just a few that come immediately to mind. The main hardship with doing property binding in C++ is you have to think a little, which is not that bad at all if you ask me. And it is not always a good thing to relieve people of thinking, just look at the disaster the relieving of physical activity has done to the world - an epidemic of overweight and obesity. Believe it or not, this happens to the mind too. That is partially why people coming from other languages find C++ such a pain. It is like making a fat guy run for his meal :D He won't like it despite the fact it is actually good for him.
-
I just would like to throw my 2 cents in:
If there were a C++ API as alternative to QML then one could write a code generator/compiler that translates QML code into native C++ code that uses this API. This would let you profit from the advantages of both worlds:
- Code can easily be maintained by editing QML files.
- During development you can profit from the fact that you don’t need to recompile after every change you make.
- The compiled C++ code obviously is more efficient.
- API changes wouldn't be as dramatic because the code generator could be used to recompile the sources incorporating the API changes.
- You can protect your IP, because the released software won’t include QML code (be it an embedded resource or not).
While I am not as concerend about the efficiency gain (or drawback) I am concerned about being able to protect IP, and this is my reason why I would appreciate a C++ interface plus such a compiler.
-
The way I think it is best used and why it doesn't need a pure C++ API:
C++:
- The application's shell
- Custom QQuickItems for application components needing performance
- Heavy parts of the application's logic exposed as slots through QML plugins/global objects
QML:
- UI layouts
- Light parts of the application's logic
I think that a pure C++ API can only be slightly more efficient for most use case, and I think that the maintenance and complexity costs of both a QML and C++ binding systems would not be worth paying for those benefits.
As much as I like signals and slots, I don't want to have to write a slot for every single connection between Rectangles/MouseAreas in the app that involve more logic than a direct value binding.
If a component of an application really requires ultimate efficiency, it is then better to go directly down to the metal with the current scene graph API to avoid as much abstraction as possible.The real question to be polled should be "Should we expose QQuick* and QSG* classes in the public API?". And for the sake of the quality of Qt5's future API, the answer should remain "no" at least until 5.1 or 5.2.
-
If you assume for the moment that there is a way to deal with binary compatibility, then I think that the arguments typically boil down to one of more of:
- QML is just so much more readable and easier to use that I can't imagine anyone ever wanting to use C++
- You can't easily do things in C++ that you can do easily in QML
- You can't do declarative in C++, because C++ is a imperative language
My concern is that people really aren't understanding what a well defined C++ interface would allow and are thus rushing to an incorrect judgement on items 1-3 above. To better illustrate the kinds of things that could be, I took a segment of QML from the Qt4.8 documentation that has animations and states and converted it to a hypothetical C++ API based description. These are shown below. From this, you can see that the C++ version is not necessarily overly verbose or less understandable than the QML version.
Note the C++ version implicitly uses various recent C++ language features to simplify and streamline the resulting code. This illustrates another reason why C++ is better in general than QML - that is, C++ has a myriad of language-based that have been intensively developed and refined over 30 years, culminating in C++11 which is supported by all major compilers now. Language design is notoriously difficult to do right and QML cannot hope to compete with C++ in this area.
C++ also enables a use of a wide variety of libraries that can be incorporated into the UI design if desired. These libraries include the C++ std library as well as Boost and many others. QML also cannot hope to compete with C++ in the area of available libraries that can be leveraged if desired. Now you may say, "well, for UI I don't need any libraries, so that doesn't matter". The response to this is, "maybe you can't imagine using any libraries, but that doesn't mean that someone else doesn't have a need to use some crazy library." For example, you might want to use some graph library (of which there are many available) to help create your UI. But with QML, this becomes a lot more tedious to do.
Now you might argue that a "designer" isn't going to use C++, to which I would probably say, yes, you're right, but they're probably not going to use QML directly either. They're more likely to use a tool like QtCreator and a such a visual design tool doesn't inherently require QML (e.g. QtDesigner doesn't use QML).
@====================== QML version =================
import QtQuick 1.0Rectangle {
width: 400
height: 400Rectangle { id: coloredRect width: 100 height: 100 anchors.centerIn: parent Behavior on color { ColorAnimation {} } MouseArea { id: mouser anchors.fill: parent hoverEnabled: true } states: [ State { name: "GreenState" when: mouser.containsMouse PropertyChanges { target: coloredRect color: "green" } }, State { name: "RedState" when: !mouser.containsMouse PropertyChanges { target: coloredRect color: "red" } }] }
}
====================== C++11 version =================
#include <QtQuick2>class OuterRect : Rectangle {
struct InnerRect : Rectangle {
MouseArea mouser;
slist<State> states;InnerRect(Rectangle *parent) : Rectangle(100,100), mouser(this) { colorChanged().connect(&ColorAnimation); anchors().centerIn(parent); mouser.anchors().fill(this); mouser.hover_enabled(true); states = { { "GreenState", mouser.containsMouse, { this.color, "green" } }, { "RedState", unary_negate(mouser.containsMouse), { this.color, "red" } } }; } } coloredRect ; OuterRect() : coloredRect(this), Rectangle(400, 400) {}
};
@ -
I agree it's beautiful, and nobody is against a pure C++ API.
It is just usually smart to offer and support only one solution for a given problem, and offering only a C++-only API wouldn't be as good as what QML has to offer to reduce application development costs.
QML has both pros and cons compared to C++, and it's part of the reasons why the Qt Quick scene graph isn't tightly coupled with QML/QtDeclarative. JavaScript isn't mandatory to be able to use the new graphics pipeline.
So overall something had to be chosen to be shipped with Qt 5.0 to offer a complete solution, and it doesn't imply that this will be the de facto solution for all 5.x releases.
-
[quote author="c++freeloader" date="1335227533"]From this, you can see that the C++ version is not necessarily overly verbose or less understandable than the QML version.[/quote]
I disagree, I think the QML version is much easier to read/understand (and to write) than the hypothetical C++ version.
In the C++ version, you need to deal with low-level concepts like variable declarations vs definitions, constructors, initialization lists, pointers, class definition vs instance, signals & slots, etc.
Not that a Qt developer would have a problem to understand any of those, but interpreting foreign code that has all those concepts tightly thrown together takes a lot more mental effort than understanding a declarative object tree consisting of clean, uniform statements of one of the forms
@ Element { ... }
property: ...
property: [..., ..., ... ...]@
...for which the parser will perform all the necessary "instantiating" and "connecting" automatically.C++ just isn't optimized as a clean declarative definition language for in-place defined nested objects. The model of... 1) class definition 1a) member declarations 1b) constructor for member definitions 2) class instantiation ...is inconvenient for such a straight-forward declarative use-case and puts information that belongs together in separate places (which, if several levels of nested objects are defined, can become quite far apart for the outer objects).
Also, the "streamlining" (as you call it) which you demonstrate e.g. for defining a state as...
@{ "GreenState", mouser.containsMouse, { this.color, "green" } }@
...looses the readability advantage of QML's "named property statements" idiom and doesn't really seem to appreciate the intended flexibility of such objects (most properties of most elements are optional, most elements allow child-elements, it should be easy to add more properties or potential child-elements in future versions).As for practicality of implementation, I haven't dug too deep into the possibilities of C++11 yet, so I might be overlooking a few things that could be handled behind the scenes in your example, but I'm wondering...
In the C++ version, how would the Qt Quick engine know when to re-calculate the value of "mouser.containsMouse" and "unary_negate(mouser.containsMouse)"?As for the usefulness, how much would really be gained? A runtime cost would still incur during loading of the Qt Quick scene.
As I understand it, what the Qt Quick engine does is:Translate QML input into an optimized internal object tree.
Run the Qt Quick scene according to those object definitions.
With you C++ API, it would become:
Translate C++ object tree input into an optimized internal object tree. (And no, I don't think letting the two be the same is feasible.)
Run the Qt Quick scene according to those object definitions.
Regarding verbosity, you cheated a little by using a pretty concise coding style for the C++ example, but a line-number wasteful coding style for the QML version.
This is how the QML example would look with a coding style that's similarly-concise as the one you used for the C++ example:@import QtQuick 1.0
Rectangle {
width: 400; height: 400Rectangle {
id: coloredRect
width: 100; height: 100
anchors.centerIn: parentMouseArea { id: mouser; anchors.fill: parent; hoverEnabled: true } states: [ State { name: "GreenState"; when: mouser.containsMouse PropertyChanges { target: coloredRect; color: "green" } }, State { name: "RedState"; when: !mouser.containsMouse PropertyChanges { target: coloredRect; color: "red" } } ] Behavior on color { ColorAnimation {} }
}
}@ -
And a point about the run-time cost of parsing / translating of QML, the same thing exists in OpenGL, with GLSL snippets needing to be compiled into GPU-specific internal shading language by the driver's built-in compiler. Still, the result is high performance 2D / 3D graphics, and not that many people are complaining about it.
-
[quote author="jdavet" date="1335386303"]
I disagree, I think the QML version is much easier to read/understand (and to write) than the hypothetical C++ version.[/quote]
"easier" - maybe, though that I guess depends on personal preferences, how much prior experience with QML, degree of comfort with JS, how much you understand the object model, and so on. "Much easier" - that is hard to argue. And I wasn't arguing that QML is much easier to understand, I was arguing, "... not necessarily overly verbose nor less understandable than QML".
[quote author="jdavet" date="1335386303"]In the C++ version, you need to deal with low-level concepts like variable declarations, constructors, initialization lists, pointers, class definition vs instance, signals & slots, etc.[/quote]
As far as I can tell, the property statements are not too dissimilar from "variable declarations". A property that already exists in a super-class doesn't need to be declared either. i.e. if you just want to assign it, you can do that. Moreover, if you want, using C++11, you can put the initialization directly at the point of declaration. e.g.
@ struct Foo {
int width = 100; int height=200;
...
};@If you're worried about having to declare the "type" of the variable, this is only necessary for newly defined properties and you can argue that static typing has some advantages and some disadvantages to dynamic typing (which is what QML in effect uses). You can always use "auto" to avoid having to think too hard about the exact type you want. Admittedly, having to specify a type or "auto" does add one more word to the description - hardly making QML "much easier" to understand.
I'm not sure how you're criticizing "initialization lists", when after all, QML has essentially the same thing, though again, much less flexible. You don't after all have to use initialization lists. Because it's C++, there are many different ways to do it, depending on the specific needs at the time. For example, say you had an arbitrary number of items to set up and each had to have some specific computation to compute location, color, size, etc. To do this in QML, now you're forced to jump through hoops (which makes it harder to understand BTW). With C++ you can do it however you want.
It's hard to argue that a class definition and instances are all that much harder to use than a purely instance based thing. The programming world (as well as many other disciplines) has pretty much settled on the concept of definitions and instances, because it allows easy reuse. You can argue that the rest of the world is stupid, but that's a pretty hard argument to win.
"signals and slots" - again, I find myself wondering what you're talking about - it's not as though in QML you don't have to have signals and slots. In QML, you have to put them in using "when: <signal>" - not too much different than saying "<signal>.connect(functor)". And you can use C++11 lambda's to allow in-place definition of the slot. Or you can do pretty much anything else to your heart's content. The point is, it's flexible to suit the needs of everybody. And all this flexibility works out of the box. Don't need to spend a dozen or more Nokia engineers to reinvent the wheel when something already exists that works well - as so many are so fond of repeating ad-nauseum when it comes to implementing a C++ API. (Sounds a bit hypocritical, but hey, that's just me)
(continued...)
-
(continuation from previous post...)
[quote author="jdavet" date="1335386303"]
Not that a Qt developer would have a problem to understand any of those, but interpreting foreign code that has all those concepts thrown together takes a lot more mental effort than understanding a declarative object tree consisting of clean, uniform statements of one of the formsC++ just isn't optimized as a clean declarative definition language for in-place defined nested objects. The model of... 1) class definition 1a) member declarations 1b) constructor for member definitions 2) class instantiation ...is inconvenient for such a straight-forward declarative use-case and puts information that belongs together in separate places (which, if several levels of nested objects are defined, can become quite far apart for the outer objects).[/quote]
You can make a syntax as clean and simple as you want by further restricting the use cases for the syntax. If I develop a language to describe circles, I can just use a single number - the radius. The problem comes when you actually want to live in reality. You'll have a hard time convincing anybody that QML has been sufficiently used on enough "real" non-toy projects to know that it has sufficient syntax to support all reasonable use-cases. Especially when there is not a single example that I'm aware of where QML has been used to develop non-trivial applications. If you have an example, please post so I can be impressed. C++ has been used on an uncountable number of "real" applications. It's been in development over 30 years. Naturally, the syntax and language facilities have grown to support "real world" applications. The point again is even with all this extra flexibility and support for real world apps that, "... not necessarily overly verbose nor less understandable than QML".
[quote author="jdavet" date="1335386303"]
Also, the "streamlining" (as you call it) which you demonstrate e.g. for defining a state as...
@{ "GreenState", mouser.containsMouse, { this.color, "green" } }@
...looses the readability advantage of QML's "named property statements" idiom and doesn't really seem to appreciate the intended flexibility of such objects (most properties of most elements are optional, most elements allow child-elements, it should be easy to add more properties or potential child-elements in future versions).[/quote]
Well, if you don't like that method, you can pick from 20 other C++ ways to do the same thing. If I don't like "named property statements" in QML, what other choices do I have? Not many.[quote author="jdavet" date="1335386303"]
As for practicality of implementation, I haven't dug too deep into the possibilities of C++11 yet, so I might be overlooking a few things that could be handled behind the scenes in your example, but I'm wondering...
In the C++ version, how would the Qt Quick engine know when to re-check the value "mouser.containsMouse" ?[/quote]Just like any other signal somehow "knows" when it's been emitted. Something in the implementation does the emitting.
[quote author="jdavet" date="1335386303"]
As for the usefulness, how much would really be gained? A runtime cost would still incur during loading of the Qt Quick scene.
As I understand it, what the Qt Quick engine does is:translate QML input into an optimized internal linked object tree in memory
run the Qt Quick scene according to those object definitions
With you C++ API, it would become:
translate C++ object input into an optimized internal linked object tree in memory
run the Qt Quick scene according to those object definitions
[/quote]
They are both declarative after all. Something must translate from the declarative description into something that is processable by the CPU/GPU.[quote author="jdavet" date="1335386303"]
Regarding verbosity, you cheated a little by using a pretty concise coding style for the C++ example, but a line-number wasteful coding style for the QML version.
This is how the QML example would look with a coding style that's similarly-concise as the one you used for the C++ example:@
import QtQuick 1.0Rectangle {
width: 400; height: 400Rectangle {
id: coloredRect
width: 100; height: 100
anchors.centerIn: parentMouseArea { id: mouser; anchors.fill: parent; hoverEnabled: true } states: [ State { name: "GreenState"; when: mouser.containsMouse PropertyChanges { target: coloredRect; color: "green" } }, State { name: "RedState"; when: !mouser.containsMouse PropertyChanges { target: coloredRect; color: "red" } } ] Behavior on color { ColorAnimation {} }
}
}@
[/quote]I'd hardly call it cheating - I just copied and pasted from the docs - written presumably by the QML developers themselves. If anything, what you wrote looks even more similar to the C++ version I provided - further evidence that C++ provides nearly all the readability and succinctness of QML. At the same time, C++ provides dozens of other significant advantages. Since these have been stated so many other times, I will not repeat them here.
-
bq. You’ll have a hard time convincing anybody that QML has been sufficiently used on enough “real” non-toy projects to know that it has sufficient syntax to support all reasonable use-cases.
Do you consider a browser a toy project? http://snowshoe.cc/
-
[quote author="capisce" date="1335392258"]
Do you consider a browser a toy project? http://snowshoe.cc/[/quote]I looked at the source code, qml and all. Looks like a marketing gimick. So to answer your question a little more pointedly, yes I consider this browser to be a toy project in the sense of what would be required for an even moderately complex application of the likes that have been done using Qt in the past. If these guys had actually rendered the web pages using QML or even had some heavy duty interaction between QML and C++ to render the web pages, then I would have been highly impressed. As it is, WebKit is doing 99.999% of the work and QML is used to create some tab widgets and a few other things. This isn't very convincing as to why one should use QML versus C++. Let us see QtDesigner or QtCreator done in QML and then we'll start to believe that QML has everything you need to build applications of "real world" variety.
-
[quote author="capisce" date="1335387147"]And a point about the run-time cost of parsing / translating of QML, the same thing exists in OpenGL, with GLSL snippets needing to be compiled into GPU-specific internal shading language by the driver's built-in compiler. Still, the result is high performance 2D / 3D graphics, and not that many people are complaining about it.[/quote]
For me personally, performance of QML is not high on my prioritized list of concerns. For me, the prioritized list would consist of:
Effectively disallowing the use of C++ to access any "modern" improvements to Qt GUI framework even though C++ is radically more flexible and has many language features and pre-existing libraries that could be put to good use to simplify design of non-toy GUIs.
Requirement to use QML to gain access to most recent Qt backend functionality, even though QML has been demonstrated to not have any signficant advantages over a hypothetical C++ API
QML is not proven to be useful to develop non-trivial apps (and no, Snowshoe isn't non-trivial application of QML). Language design is notoriously difficult to do right. C++ has been on the development path for 40 years (if you take C as a starting point). QML will never compete against that. qmake is at least one example of a hacked up language.
Requirement to learn a new language that has no use anywhere outside of Qt
Requirement to use JS (yes, I know you don't really need it, but from what I've seen, all non-trivial apps use it to some extent)
Requirement to learn JS when JS provides no significant benefit and is only really beneficial if doing significant amounts of web development.
Opportunity cost of Qt developers putting the cart before the horse and spending their finite resources on reinventing the wheel, rather than moving the framework forward in fundamental new ways.
Need to jump through hoops for anything more than minor QML/C++ integration.
Performance and run-time cost of QML/JS in comparison to compiled C++. Yes, they both must populate the scene-graph, but one must parse the QML and JS and then JIT the JS and finally execute it in order to populate the scenegraph. Sufficient performance for toy apps doesn't imply sufficient performance for non-toy apps. Also, why waste energy for mobile apps where battery life is so important especially when there's no good reason to do so. BTW, memory footprint will be bigger as well. In addition the footprint of all the supporting infrastructure (e.g. V8)
Lack of debuggability of QML and JS. If something were wrong in the implementation of QtQuick, you can't simply pull up GDB and single-step the code (which I've done with QWidgets). With a pure C++ paradigm, you can still do that. Again, by taking this step of defining a whole new language and runtime system, Qt developers have bitten off more than they can chew. Now they need a QML debugger. They should be leveraging as much stock stuff as they can and using their development resources/talents to really add value in places that matter.
Requirement for OS to support V8 JS engine. This is specifically bad in the case of iOS where it may be that Qt5 will not be runable due to this. Maybe this will not be a problem, but at this point it could very well be. Of course Nokia doesn't care about this (even though, for their own good, they should strive to be the leading provider of cross-platform development environment - but this is another whole thread).
Inability to use any of the readily available C/C++ static code analyis tools (e.g. Clang static analyzer) to help find bugs in JS script and other aspects of the UI.
-
I think some people are taking the wrong direction, the usage of JavaScript provides some benefits that cannot be realized in C++ through the same workflow. I don't think there should even be an attempt to make QML and C++ interchangeable to operate on the same type of objects. Not only because stock QtQuick components have a lot of QML specific stuff, but because they are optimized for use through QML, which is less flexible than subclassing objects in C++, thus the need of JS to overcome that lack of flexibility.
I fully realize it may very well require the design and creating of new components for an eventual C++ api, it would be the right thing to do, and the workflow will be a little different. For example, the type of property binding in QML is unnecessary complicated to emulate in C++, not that it can't, but there is really no need to do it exactly the same way, since C++ offers a more efficient ways, for example, overload the parent updateEvent and put binding code there, to be executed before each redraw.
I have read that other discussion people have been trying to redirect this thread into, and some people appear to have gotten the main point, we need a new and fully hardware accelerated GraphicsView, that I assume can be implemented through the SceneGraph, not simply slammed on top of it as it is currently done in Qt5. A hardware API centered aroung making avaiable and easy stuff like:
-
- built entirely on top of OpenGL/ES, the option of reaching into the 3rd dimension
-
- easy animation, state based, tween based, with control curves, timelined, etc...
-
- hardware accelerated drawing, using shaders that can easily offer 20-30 times performance increase
-
- easy integration of 2D shader based effects, like it is currently done for QML
-
- easy integration of 3D geometry and shading, a 3D centered sub-API with basic modelling and modifier capabilities
-
- better optimized for texture caching, automatic texture redraw when needed, draw and cache several states at once so even common static changes like button over, pressed are not continuously redrawn
-
- shared texture caching so that identical components or sub-components are efficient
-
- automatic multi-pen drawing to avoid costly painter state changes
-
- 2d and 3d collision detection, hardware accelerated IK animation and physics
-
- easy media IO - audio, video, image
-
- platform independence, so its features can easily be ported by the community to mobile platforms that are not dead end, since it doesn't seem Nokia will ever bother doing it
-
- OpenCL processing if supported, fallback to lower precision through OpenGL when absent
Making a native API with such capabilities is far more important and beneficial in the long run, and if that hypotetical API has a well designed fronted, I bet we'll see new components, optimized for it, stack up very rapidly, not even requiring Troll efforts, but entirely through the community.
I know that you can use GraphicsView, you can put it on top of a OpenGL widget and get some performance boost in many cases, I know you can use QQuickPaintedItem to get a custom painting item in QML(and be conformed to it), but those aren't really solutions.
Such an API, described above will effectively grant developers ultimate freedom, the ability to do advanced applications very few API's can offer out of the box and none of them can offer the speed and efficiency of native, platform specific binary. From basic, modern and fluid 2d UI, through 3d games and CAD applications, not just an API for the user interface, but an app engine. Adobe have already a solution like that, ever since the introduction of Stage 3D, capable of delivering astonishing "results":http://alternativaplatform.com/en/demos/crash/ , and Qt can the potential to do it even better, if unrestrained by the poor efficiency of interpreted languages.
I've been developing applications using Flash, but the moment you reach into some extensive logic, performance isn't there, AS is just as poorly performing as JS. I wasn't that aware of the fact until the moment I tried running Sumopaint on my tablet, on a PC Sumopaint works just fine, but on my Tegra2 tab performance was so poor the app wasn't really usable. Even apps written in Java, which is way better than JS are still sluggish compared to the little drawing app I developed and ported to Android with Necessitas, which has outstanding performance. I realize there aren't that many companies with the capacity to do something as advanced as Adobe did, but better, or in other words C++ NATIVE, but Qt comes very close to being able to provide such an API, because currently there is no similar API in existence (the little that to exist are either based on a slow programming language or not platform portable at all), which will inevitably translate into a huge advantage and make Qt very attractive to a wide range of software developers by offering something truly unique and irreplaceable (unlike QML)...
-
-
@c++freeloader
bq. If these guys had actually rendered the web pages using QML or even had some heavy duty interaction between QML and C++ to render the web pages, then I would have been highly impressed. As it is, WebKit is doing 99.999% of the work and QML is used to create some tab widgets and a few other things.
The UI is exactly what QML is meant for for, WebKit already has its own renderer. Noone's saying you should do everything in QML. Even if Creator were to make most of its UI based on QML, it would probably still want to write the code editor widget with a high dose of C++, since it's such a highly application specific component with very custom needs. You wouldn't expect Maya to write their 3D renderer in QML, but it could certainly be used for parts of their UI.
Here's another example of an application that has seen quite some use, a Spotify client for MeeGo: https://qt.gitorious.org/qt-labs/meespot/trees/master
bq. Requirement to use QML to gain access to most recent Qt backend functionality, even though QML has been demonstrated to not have any signficant advantages over a hypothetical C++ API
I've already mentioned that the base enablers QQuickItem (corresponding to Item in QML), QSGNode, etc are public API. It's just the sub classes of QQuickItem, such as Rectangle, MouseArea that are not exposed as C++ API at this point.
-
[quote author="c++freeloader" date="1335391023"]C++ has been used on an uncountable number of "real" applications.[/quote]
Altough usually not as a pure declarative object-defining data language. Either XML or some custom solution has usually filled that role, even for C++ applications.
[quote author="c++freeloader" date="1335391023"]Well, if you don't like that method, you can pick from 20 other C++ ways to do the same thing. If I don't like "named property statements" in QML, what other choices do I have? Not many.[/quote]
20 different-looking ways to do the same simple thing, is not exactly a readability and maintainability dream come true. At least not unless all code you will ever deal with was written by yourself (and you can still remember what you thought when you wrote it).
[quote author="c++freeloader" date="1335391023"]Just like any other signal somehow "knows" when it's been emitted. Something in the implementation does the emitting.[/quote]
But "mouser.containsMouse" is not a signal, it's a property (which at any point in time can be either true or false).
[quote author="c++freeloader" date="1335391023"]Something must translate from the declarative description into something that is processable by the CPU/GPU.[/quote]
No, into an internal declarative description that is processable by the Qt Quick engine.
Unless you choose to embed JavaScript expressions or GLSL shader snippets inside your QML source, I don't think there will be any byte code compilation of any sort. The only thing that gets passed to the CPU is the compiled Qt Quick engine's code (which was written using C++).
-
[quote author="jdavet" date="1335455361"]20 different-looking ways to do the same simple thing, is not exactly a readability and maintainability dream come true. At least not unless all code you will ever deal with was written by yourself (and you can still remember what you thought when you wrote it).[/quote]
The point is that in the real world, there are many ways of doing things for a reason. A language dictating the "one-and-only correct and true way" is a language that hasn't yet been used in the real world. A book for a 3 yr old is easy to read too. Doesn't mean that it's going to be considered a literary class.[quote author="jdavet" date="1335455361"]But "mouser.containsMouse" is not a signal, it's a property (which at any point in time can be either true or false).[/quote]
A property that has the semantics of a signal.[quote author="jdavet" date="1335455361"][quote author="c++freeloader" date="1335391023"]Something must translate from the declarative description into something that is processable by the CPU/GPU.[/quote]
No, into an internal declarative description that is processable by the Qt Quick engine.[/quote]
Which is ultimately imperatively executed by a CPU/GPU. Do you like arguing for arguing sake or do you actually have a point? -
QML introduces a significant performance overhead, due to beeing executed in a JavaScript-based virtual machine, and is introducing lots of glue code, glue abstract and proxy objects.
QML is analyzed once at the time a source file is loaded to build a native representation, which then provides the same performance as beeing created in native C++ code. A compiler is beeing evaluated, which would shift analysis from run-time to compile-time, but as performance metrics have shown that the current run-time overhead is minuscule, it is currently on low priority.
QML (as beeing a declarative language) doesn't require JavaScript, it is (theoretically) possible to build and use Qt Quick and QML without any JavaScript interpreter at all. Qt Quick uses JavaScript just to evaluate imperative code and non-trivial bindings. Everything else results in native code.
There is no requirement for additional glue code or proxy objects to expose data from C++ to QML. Existing objects (QObject), collections (QStringList, QObjectList) and models (QAbstractItemModel) can be directly exposed to and used in QML, signals and slots are routed transparently and both, C++ and QML, can modify object properties. For doing so, Qt Quick utilizes the Meta-Object Information that is generated by <code>moc</code> and already present for every object in Qt.
Former native applications become non-native due to the use of QML.
QML is used to build a native representation, as other non-native, domain-specific, interpreted languages already present in Qt and every Qt application, like CSS, SQL or PCRE.
QtQuick requires applications to be created in QML and JavaScript, the advantages of the new graphical arichtecture (SceneGraph) can be used from QML only and C++ has been deliberately left out to push QML, which has made QtWidgets and The Graphics View Framework obsolte.
QtQuick exposes the API to C++ where meaningful and the SceneGraph can be used using both, QML and C++, one without the other. This includes all the building blocks for QtQuick, including the Animation Framework, the State Machine Framework and the Graphics View Framework (all of them beeing there before QtQuick). Every object created in QML is accessible in C++ and QML is fully extensible using C++. However, there is a trade-off between exposing internal classes of QtQuick and thus introducing binary contracts and the value to the developer (which is actually low, as there is no support for most QML features in C++).
The application and the business logic itself is still expected and required to be made in C++, because QML is mainly used to build user interfaces, not applications - the same way CSS is used to style QtWidgets, SQL is used to query data and PCRE is used to do string analysis.
QtWidgets and The Graphics View Framework are still first class citizens in Qt, they still can be used and will be used to create applications, they will receive attention on part of the developers and there are still additions made (there has been a quite impressive charting component released just a few weeks ago). QtQuick is optional, there is no obligation for new applications to use it, and there is no requirement to port existing applications.
However, you cannot use SceneGraph with QtWidgets, because the imperative drawing model of QtWidgets is quite incompatible with the state-based drawing model of a modern GPU (where almost all the additional performance of QtQuick comes from). This is a technical limitation.
There is no way to debug declarative user interfaces created using QML, above all not using GDB.
GDB is a debugger for imperative languages, Qt Quick / QML has its own debugger suitable for declarative languages.
There are no advantages of using QML over C++.
QML is fully network transparent, each resource can be either local or remote, including source files. In addition, there is full tool support for creating QtQuick user interfaces, which also allows for doing user interface-specific code by the designer, who usually isn't aware of C++, and thus enabling another layer of user interfaces / business logic abstraction. It is absolutely easy to learn and has a much less steep learning curve for people not beeing aware of imperative programming languages in general and C++ in specific. Beeing a declarative language featuring an imperative interpreter one gains the advantages of lazy evaluation and (non-trivial) bindings. In addition, there are almost no binary contracts introduced, which is vital for emerging technolgies.
This is not possible in C++.
-
QML is a proprietary language, it was made closed-door and political motivated, as any decisions regarding Qt. Declarative langues are quite uncommon for creating user interfaces.
QML with its JSON-like syntax and imperative JavaScript language is the result of a technical selection process. The specification and implementation is publicy available, and can be searched, modified and extended by everyone. Decisions on the future of Qt were always takes on purely technical reasons inside Nokia before open governance was fully set up. Now decisions are taken in the public — and again for technical reasons only.
Declarative user interfaces-languages are widely used and pushed, for example XAML, HTML5, XUL, SVG and Cocoa.
QtQuick / QML is a toy-language only, no real spplications have been ever created with it.
Although QtQuick / QML beeing an emerging technology, both are activly used to create and port applications, like KDE, Qt Media Hub or the Nokia N9.
C++ can be used as a declarative language as well.
QML is declarative, not imperative - JavaScript is, as well as C++. You cannot express one using the other. A C++ QtQuick API will always be imperative.
Qt5 is a primarily a QtQuick release. There are no other improvments for the classical development.
- All ports now base on the Qt Platform Abstraction Layer
- Modularization of the Qt Respository
- Improvments for QtCore, including a new way of handling standard pathes, a full-blown JSON parser, MimeType recognition, a completely new compile-time checked signal/slot connection syntax, which allows for using of C++11 lambdas, a completely new Perl-compatible regular expression parser, a rewrite of many data structures optimized for better performance and C++11 support
- Improvments for QtGui, including a port to the new QPA architecture, top-level surfaces and built-in OpenGL support
- Improvments for QtNetwork, including support for DNS lookups
- Integration of Qt3D, QtLocation, the Mobility APIs, improvments for QLocale, time handling, unicode, an updated WebKit, ...
Dynamic fluid interfaces are just for smartphones, which are still a niche market. Desktops require native looking and behaving applications.
In 2011 415 million desktops were sold. In the same time 488 million smartphones were sold, about 700.000 smartphone applications were created, 17 billion applications were either sold or downloaded for free and this number is expected to rise to 185 billion in 2014. A revenue of over 15 billion dollars has been generated, which is an increase of 190% over 2010. There is a strong momentum in classical desktop application development for user-centric and task-centric applications as well, which breaks with native platform-specific look and feel. The predominant desktop platform Windows (92.5%) completely focuses on task-centric applications within its upcoming release (Windows 8).
X is better than Y, and should take precedence over Z.
No, but there are facts, and there is fiction. Basis of discussion should be the former, not the latter.