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..)
Related
I'm trying to define a custom QT Slot/Signal for passing a QImage.
I'm using qt_widgets crate which has many predefined slot types like SlotOfQIcon. However it doesn't have one for QImage. I've looked at the source code which is generated with this tool: https://github.com/rust-qt/ritual.
Is it possible to do this in regular Rust project without running complex multistage build involving code generation?
List of implemented slots for reference:
https://docs.rs/qt_widgets/0.3.0/x86_64-pc-windows-msvc/qt_widgets/
I've tried to copy paste generated code for other widgets and modify it, but it doesn't look like a right approach. I don't want to regenerate the whole library just for this case. Are there any simpler options?
I'm using the qdbusxml2cpp tool to generate a D-Bus adaptor class for my D-Bus server. However, it has the following drawbacks:
Code is generated once, and then you're not supposed to modify it. But what if we have to make changes (see below) and then the XML changes (in a backwards compatible way, of course)?
It is assumed that the "adaptee" has the exact same functions and signatures as the D-Bus interface. In my case, that's not exactly true, e.g. some methods are named differently. Because the generated code uses QMetaObject::invokeMethod, this is only detected at runtime. And we can't sensibly modify the generated code if we might need to regenerate it in the future.
It would be much nicer, in my opinion, if qdbusxml2cpp would generate an abstract class, just a header, where all methods are pure virtual. Then I can write an implementation of that class that simply calls the right methods on the adaptee, without going through the Qt metatype system. This solves both problems:
If the XML changes, we just regenerate the header. Now the compiler will complain until we implement the new interface correctly.
We have the freedom to call whatever functions we like on the "adaptee" class, instead of maintaining the exact same signature as in the public D-Bus interface.
I couldn't find any tool or qdbusxml2cpp fork that does the above. Before I write it myself, are there any problems with the above approach that I might be overlooking, design-wise or technical? Perhaps limitations of the metatype system related to abstract classes or pure virtual functions?
Note that I need this to work not just with methods, but with properties and signals as well.
I've also considered writing an "intermediate" adaptor that wraps the "adaptee" and offers the exact interface that the D-Bus adaptor expects, but the D-Bus adaptor would still be using the metatype system and runtime checks. Surely we can do better.
As you've discovered, there's no way to do what you want with qdbusxml2cpp directly. Which means that we have a few options here, some that you've already listed out:
It would be much nicer, in my opinion, if qdbusxml2cpp would generate an abstract class, just a header, where all methods are pure virtual.
There doesn't seem to be anything terribly wrong with this, although some tools/IDEs may not play nicely with it. One downside to this is that whenever something changes, you would have to ensure that you update all parts of the C++ source as well, not just your header, e.g. if there is boilerplate that has to change whenever a new method is added.
Code is generated once, and then you're not supposed to modify it. But what if we have to make changes (see below) and then the XML changes (in a backwards compatible way, of course)?
Depending on how well the code generator works, I've sometimes found it easier to simply use the generated code as a starting point and then simply modifying it from there. Most of the chages are generally pretty simple.
One other option that you could do is to use a different library to do the DBus communications.
dbus-cxx
dbus-cpp
dbus-cplusplus
I use(and maintain) dbus-cxx; there is a tool included(dbus-cxx-xml2cpp) that generates adaptee classes that are similar to the output of qdbusxml2cpp in that the adaptee class simply calls a different class that handles the actual response. The downside is that the xml2cpp tool is not that smart, and will not always output correct code. And to use dbus-cxx in a Qt application, you need to turn off the Qt keywords. However, it does have the advantage of using templated functions, so if your signature is incorrect you will get a compile error.
Unfortunately, there isn't really a good "right" way to do this, so I'm afraid that I don't have a "Do it this way" answer.
I am creating a C++ class that will be registered as a QML type. I want to run some non-trivial logic when the object is initialized. I don't want to put this logic in the constructor because that is bad practice. In a standard C++ class I would usually create a Startup() function with this logic and call it just after initializing the object, but I have no control over this as objects are initialized in QML.
How should I implement this custom initialization logic for a custom QML type?
For those who want the details. I am making a QAbstractListModel that keeps track of all .txt files in a directory. When it is created it will scan the directory (passed in via property) and update its internal collection with the names of all .txt files in that directory.
Edit1: After looking at Qt's example projects I found that many of them actually do all initialization logic in the constructor, including things like setting up DB connections and doing an initial DB query and query parsing. One need only search for "database" from the Qt Creator Welcom->Examples screen to see these samples. I would appreciate it if someone found and explained a better way.
I am learning Qt for the first time and I prefer to learn how to things the hand-coded way. I prefer learning this route because I am using Eclipse (with no Qt Designer) and I learn better knowing what is going on under the hood. Thus, I would like to know how to hand-code the XML-based user interface definition (.ui) files.
Unfortunately, I cannot seem to find any information on how this XML tree should be structured, and which properties and attributes are allowed. Instead, I find "drag-and-drop" tutorials. Aside from generating the .ui files in Qt Designer and then studying the output XML tree, is there another way to learn how to handcode these .ui files, or any documentation which speaks to the semantics of this XML document?
Thank you!
The UI file's sole purpose is to save you from hand-coding things. They're files that are generated by designer:
You create user interface components with Qt Designer and use Qt's integrated build tools, qmake and uic, to generate code for them when the application is built. The generated code contains the form's user interface object. It is a C++ struct that contains:
If you want to improve your knowledge of Qt, learning to write UIs via C++ would be a better option. Still, if you're convinced, there is this XML schema:
http://qt-project.org/doc/qt-4.8/designer-ui-file-format.html
Note that it says:
Be aware that the format may change in future Qt releases.
You might also be interested in the documentation for uic, which operates on the .ui file to create a header file containing the various widgets that make up the UI.
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.