Qt QML and QDBus interoperability - qt

There is a property system in Qt. Properties can be exposed from D-Bus using subclassing of QDBusAbstractInterface from the one hand and to Qt QML from the other hand. For properties and signals of D-Bus services interfaces it can be done by meta-object compiler automatically. For signals, slots and properties of QObject for QML it also can be done automatically by MOC.
But the problem arises: QML needs property and method (either signal or slot) names to be started from lowercase letter, while, say, Network Manager DBus API exports objects with all members identifiers starting with uppercase letters (sometimes with lowercase letters, say org.freedesktop.NetworkManager.state() method). But I want to use such an QDBusAbstractInterface-derived objects directly into QML code.
Is there a way to automatically translate methods' and properties' names into one form for QtQml and into another form for QDBus?
Example of how to emit a signals for all the properties of NetworkManager objects separately.
Added: KDE NetworkManager Qt is not too useful in the light of the question, because there is no properties to be exported with QObject-s in QML.

Related

Qt use of Class and CLassPrivate

When examining classes written by Qt, I discover many contain a class called "Class", and another called "ClassPrivate". For example QFile contains QFile and QFilePrivate, QIODevice contains QIODevice and QIODevicePrivate.
What is the purpose of this design?
This is a common design pattern called private implementation, or pimpl for short. Qt actually calls it d/q pointer, but it is the same thing.
The Q_D and Q_Q macros are part of a design pattern called the d-pointer (also called the opaque pointer) where the implementation details of a library may be hidden from its users and changes to the implementation can be made to a library without breaking binary compatibility.
The main reason for this in binary compatibility. Qt, unlike many other projects like boost, has had the guarantee of API (source) and ABI (binary) compatibility for the same major version.
So, the API and ABI would not break e.g. inside the Qt 5.x series. They would have to change the major version to break any of this.
Now, the private implementation really helps with this as the implementation details are no longer in the publicly available header file.
They can add further private members (method or variable) in the private implementation while the public interface would still online contain a private implementation pointer.
This makes the public interface completely opaque allowing flexibility in changing the implementation details without having to worry about the public interface.
Here is an example they give:
class Widget
{
// ...
private:
Rect m_geometry;
String m_stylesheet; // NEW in WidgetLib 1.1
};
class Label : public Widget
{
public:
// ...
String text() const
{
return m_text;
}
private:
String m_text;
};
This would break the client code using Widget causing a crash. However, if you hide the implementation details of the Widget class behind a private pointer, you can do anything with it since it is hidden. So, in the above example, you can add "m_stylesheet" without any risks and the client code using Label will not crash.
In case you wonder why binary compatibility is such a big deal: Qt has been a popular framework used by many applications, some really big. It would be a major pain in the neck to upgrade the Qt dependency for them if it did not offer binary compatibility.
When designing libraries like Qt, it is desirable that applications that dynamically link to Qt continue to run without recompiling even after the Qt library is upgraded/replaced with another version. For example, if your application CuteApp was based on Qt 4.5, you should be able to upgrade the Qt libraries (on Windows shipped with the application, on Linux often comes from package manager automatically!) from version 4.5 to Qt 4.6 and your CuteApp that was built with Qt 4.5 should still be able to run.
Basically, when you upgrade Qt in this way for your application, you can just drop in the new version without even having to recompile your application. And the features of your application will just keep working as before. This is great because you do not need to send a new version of your application to the customers. They can just upgrade Qt on their side and benefit from performance improvements in Qt or bug fixes indeed, etc.
And as a matter of convention, these private implementation are written in Qt inside files with the _p.h suffix.
You can also refer to this page for further binary compatibility examples.
In Qt 4.8, we see this structure please look at this doc
But in Qt6 we don't have QFilePrivate or ClassPrivate classes. look at this
If you see in Qt 4.8 Structure of classes has one QObjectData and one QObject
for more detail, you can compare this source which was for Qt 4.8 and now the new version of QObject class.
QFile inherits QObject and QFilePrivate inherits QObjectData
What is the purpose of this design?
I guess they want to provide very strong encapsulationYou cannot access the d pointer as a user of the API, which is the whole point of encapsulation.
d_ptr is a pointer in QObject class in Qt 4.8
Look at D-Pointer document.
The trick is to keep the size of all public classes of a library
constant by only storing a single pointer. This pointer points to a
private/internal data structure that contains all the data. The size
of this internal structure can shrink or grow without having any
side-effect on the application because the pointer is accessed only in
the library code and from the application's point of view the size of
the object never changes - it's always the size of the pointer. This
pointer is called the d-pointer.
The spirit of this pattern is outlined in the code below (all code in
this article doesn't have destructors, of course you should add them
in real code).

Automating a custom QGraphicsObject control in an external QT based process

I have injected a DLL into an external application that is based on the QT framework. I then use the command QApplication::allWidgets() and iterate through the list of widgets to find a QGraphicsView that represents the window I want to interact with. The buttons and other controls in the scene are all derived from QGraphicsObject. I don't have the source, so I can only cast to QGraphicsObject and not the actual type. The list of methods from the metaobject is incomplete, which is to be expected, because I cast to a QGraphicsObject. I can find the method names using IDA though. Is it possible to call a particular method, and how would you do it?

Q_PROPERTY read only instance

Is there a way to disable write accessors for all properties for a given instance of QObject, effectively turning them into a no-op?
AFAIK: No.
The Q_PROPERTY macro triggers the moc to build the methods at compile time, so there's no way you can change their behaviour at runtime for a particular QObject derived instance.

Qt - meta object code

What do we mean by the meta object code when relating to the Meta Object Compiler (moc) in Qt?
Thanks.
Meta objects enhance programming languages by creating new or manipulate existing objects. They provide functionalities a language does not actually have by itself. The Meta Objects are interpreted either by compile time or run time. In Qt and C++ it is done during compile time by the Meta Object Compiler (moc).
An example case is the usage of the signal/slot concept.
Since you specifically asked about Meta object and moc,
From docs,
...The moc tool reads a C++ header file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces a C++ source file containing the meta-object code for those classes. ...
HTH..
Meta object code is required for Signal Slot mechanism ,Run time type information and dynamic property system.
Qt system creates "meta object code" based on "annotations" in your c++ code (eg Q_PROPERTY, Q_SLOTS etc). Qt uses them to implement meta-calls and reflection style access to class properties.
Look at the ".moc" files that the compiler produces for your class and you'll understand.
But given the uncertainty around Qt's future, may I ask why you are choosing Qt? (unless its purely for the joy of hacking..)

Q_OBJECT macro and meta-object code

This link: http://doc.trolltech.com/4.5/moc.html#moc says
The moc tool reads a C++ header file.
If it finds one or more class
declarations that contain the Q_OBJECT
macro, it produces a C++ source file
containing the meta-object code for
those classes.
What is a meta object code?
EDIT 1
How to know in which classes I should write the Q_OBJECT? One example is the signals and slots, any other cases where that needs to be used?
You can read the article Qt internals and Reversing to get in depth knowledge about Qt and its moc compiler (meta objet compiler). In summary a meta object is created by Qt's moc compiler to add extra information to a class like signal/slot mechanism etc.
Meta objects enhance programming languages by creating new or manipulate existing objects. They provide functionalities a language does not actually have by itself. The Meta Objects are interpreted either by compile time or run time. In Qt and C++ it is done during compile time by the Meta Object Compiler (moc).
An example case is the usage of the signal/slot concept.
A meta object code in Qt environment is a C++ source file that is an expanded version of the C++ source file where you've put Q_OBJECT (and/or other related macros). The meta object code will have your implementation plus some other extra (meta) code so that signal and slots mechanism work.
A meta-object contains meta-information about an object like its name and a textual description of its signals and slots. This make it possible to call signal by "name". See the documentation about QMetaObject and this article.

Resources