Dynamic XML documents instead of `.ui` files in Qt
-
The class
QUiLoader
represents elements of a graphical user interface, of Qt components, described by an XML document. A common design pattern would be a build process integrating a static document into the application as a resource. Another would be code generation at build time.Consider the possibility of describing part of a user interface through an XML document that would be dynamically constructed, such as through an XSLT transformation provided by Xalan-C++. In an XML-driven application, such a design opens possibilities not readily available from more widespread patterns.
Yet, it may appear from the documentation that the only interface for passing XML data to be utilized by
QUiLoader
is through the invocation of the methodload()
invoked by passing an instance ofQIODevice
. Such a call supports streaming data of serialized form. Naturally, intermediary serialization or parsing operations are unnecessary, at least in principle, and unpreferred.Following are two questions:
- Is such a strategy viable, in terms of authoring a Qt application for which some of the presentation layout is resolved dynamically in such a manner?
- Is a superior approach available, for displaying presentation represented by a dynamically-generated XML document, compared to passing a string representation of it, through Qt?
-
QUILoader indeed allows to load .ui files at runtime, via QUILoader::load(). How you end up with the XML that constitutes the XML file is up to you. So yeah, I don't see why your setup shouldn't work. Keep in mind though that, compared to the more traditional uic approach, you're moving work from compile time to runtime, which makes error checking harder, but also creates some delay at runtime.
One alternative is using Qt Quick, and it's language QML. This is not XML though, but you could of course generate a QML file out of an XML file by transformation.
-
Yet, it may appear from the documentation that the only interface for passing XML data to be utilized by QUiLoader is through the invocation of the method load() invoked by passing an instance of QIODevice. Such a call supports streaming data of serialized form. Naturally, intermediary serialization or parsing operations are unnecessary, at least in principle, and unpreferred.
Well, XML by definition is serialized. If you want to start with something like a in-memory DOM, you could implement your own UILoader functionality quite easily, but there's no ready-made API for that.
If your concern is only that you don't want to do disk-io, please be aware that a QIODevice can also be a purely in-memory data storage, like QBuffer.
-
@kkoehne said in Dynamic XML documents instead of `.ui` files in Qt:
Well, XML by definition is serialized. If you want to start with something like a in-memory DOM, you could implement your own UILoader functionality quite easily, but there's no ready-made API for that.
If your concern is only that you don't want to do disk-io, please be aware that a QIODevice can also be a purely in-memory data storage, like QBuffer.The concern is not about avoiding I/O, but about being forced to use serialized form as the only available means for passing a document in memory.
Would you please clarify the sense in which implementing the functionality of
QUiLoader
is "quite easy", as doing so would seem to me to involve completely creating a processor for the semantics of the UI language, to build a widget representation based on the content of the UI document, as I understand to be the function ofQUiLoader
. -
@brainchild said in Dynamic XML documents instead of `.ui` files in Qt:
The concern is not about avoiding I/O, but about being forced to use serialized form as the only available means for passing a document in memory.
What does this mean? You somehow must pass the data to the uiloader class. And this is a QIODevice which can be a QFile or QBuffer or something else.
-
@brainchild said in Dynamic XML documents instead of `.ui` files in Qt:
Would you please clarify the sense in which implementing the functionality of QUiLoader is "quite easy", as doing so would seem to me to involve completely creating a processor for the semantics of the UI language, to build a widget representation based on the content of the UI document, as I understand to be the function of QUiLoader.
"quite easy" was probably an exaggeration. What I meant is that such a mapping is conceptually not complicated - The C++ API of Qt Widgets allows you to do stuff imperatively, after all. But depending on the scope (which widgets, properties, ... you want to support), it might still be a lot of work, sure.
-
@Christian-Ehrlicher said in Dynamic XML documents instead of `.ui` files in Qt:
@brainchild said in Dynamic XML documents instead of `.ui` files in Qt:
The concern is not about avoiding I/O, but about being forced to use serialized form as the only available means for passing a document in memory.
What does this mean? You somehow must pass the data to the uiloader class. And this is a QIODevice which can be a QFile or QBuffer or something else.
Usually serialized form is for I/O, not internal processing. It may work in principle to pass serialized strings across an application, but is not preferred. Most processing of XML documents at some point requires a random-access negotiation of the tree, hence the emergence of DOM.
-
@kkoehne said in Dynamic XML documents instead of `.ui` files in Qt:
"quite easy" was probably an exaggeration. What I meant is that such a mapping is conceptually not complicated - The C++ API of Qt Widgets allows you to do stuff imperatively, after all. But depending on the scope (which widgets, properties, ... you want to support), it might still be a lot of work, sure.
Exact congruity in behavior is hard requirement.
-
@brainchild The uiloader is just a way to load xml files which in 99,9% are processed by uic and compiled directly instead. So adding this complexity to pass a DOM instead a simple QIODevice for the max. 0,1% use case is fine in my pov.
Esp.since there is no need for a DOM and QtCore don't have a DOM class at all - QXmlStreamReader is perfectly fine for this simple task. -
@Christian-Ehrlicher said in Dynamic XML documents instead of `.ui` files in Qt:
@brainchild The uiloader is just a way to load xml files which in 99,9% are processed by uic and compiled directly instead. So adding this complexity to pass a DOM instead a simple QIODevice for the max. 0,1% use case is fine in my pov.
Esp.since there is no need for a DOM and QtCore don't have a DOM class at all - QXmlStreamReader is perfectly fine for this simple task.It would be an improvement, though, if the builder were not tied to I/O or strings, even if mostly it would be used in such a way. The class
QXMLStreamReader
could be refactored to descend from an abstract parent, which could be used as a source for the builder, as a parameter to a new method, with the builder then being refactoring such that the existing methods would utilize the new one.At any rate, I understand the responses given, that any application based on the current platform must use strings if not I/O.
-
@Christian-Ehrlicher said in Dynamic XML documents instead of `.ui` files in Qt:
@brainchild The uiloader is just a way to load xml files which in 99,9% are processed by uic and compiled directly instead. So adding this complexity to pass a DOM instead a simple QIODevice for the max. 0,1% use case is fine in my pov.
Esp.since there is no need for a DOM and QtCore don't have a DOM class at all - QXmlStreamReader is perfectly fine for this simple task.The XML module has a DOM representation. Why would it not be sensible for a version to be provided of
load()
that processes a DOM representation from this module?