IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
FAQ Qt FAQ Qt Creator FAQ PyQt & PySide

FAQ Qt

FAQ QtConsultez toutes les FAQ

Nombre d'auteurs : 26, nombre de questions : 298, dernière mise à jour : 15 juin 2021 

 
OuvrirSommaireGénéralités techniquesMétaobjets

La classe QObject (et donc toutes les classes dérivées) possède la variable

 
Sélectionnez
protected :
    static const QMetaObject staticQtMetaObject;

Cette instance donne accès aux métadonnées de l'espace de noms de Qt. Les métadonnées accessible sont exclusivement des énumerateurs.

Voici un exemple qui affiche sous forme d'arbre tous les énumérateurs de l'espace de noms de Qt et leurs valeurs.

 
Sélectionnez
#include <QtGui>
 
class monWidget : public QWidget
{
    QAbstractItemModel * createModel()
    {
        QStandardItemModel * model = new QStandardItemModel(this);     
 
        // parcours de toutes les enum du namespace Qt
        for (int i = 0; i < staticQtMetaObject.enumeratorCount(); ++i)
        {
            // ième enumerateur
           QMetaEnum iEnum = staticQtMetaObject.enumerator(i);
 
           QStandardItem * parent = new QStandardItem(iEnum.name());
           // parcours de toutes les valeurs de l'enum 
           for (int j = 0; j < iEnum.keyCount(); ++j)
           {
                QList<QStandardItem *> items;
 
                // jième valeur de l'enum
                int value = iEnum.value(j);
 
                // chaîne correspondant à la valeur dans l'enum
                items << new QStandardItem(iEnum.valueToKey(value));
 
                // valeur sous forme hexadécimale
                items << new QStandardItem("0x0" + QString::number(value,16).toUpper());
 
                parent->appendRow(items);
            }
            model->appendRow(parent);
        }
        model->setColumnCount(2);
        model->setHeaderData(0, Qt::Horizontal, "Enumerateur", Qt::DisplayRole);
        model->setHeaderData(1, Qt::Horizontal, "Valeur", Qt::DisplayRole);
        return model;
    }
public :
    monWidget()
    {
        resize(400,600);
        QVBoxLayout * layout = new QVBoxLayout(this);
        QTreeView * treeView = new QTreeView;        
        treeView->setModel(createModel());   
        treeView->header()->setResizeMode(QHeaderView::ResizeToContents);
        layout->addWidget(treeView);
    }
};
 
int main(int argc, char * argv[])
{
    QApplication app(argc,argv);
    monWidget widget;
    widget.show();
    return app.exec();
}

Comme staticQtMetaObject n'est pas documenté, cela est susceptible d'être modifié dans une version future de Qt.

Créé le 7 mai 2012  par Yan Verdavaine

Le moc n'extrait et ne stocke pas les informations de toutes les méthodes mais uniquement celles qui sont indiquées comme nécessitant ces opérations. Par exemple, les informations d'un constructeur déclaré dans la section publique sans instruction particulière au moc ne seront pas extraites, tandis que les méthodes déclarées dans la partie des signaux le seront. Pour que le moc recense une méthode, il faut soit la définir en tant que signal ou slot, soit utiliser une instruction particulière.

Voici les principales instructions utilisables pour signaler au moc que le recensement doit être effectué, ainsi que leur effet :

  • Q_INVOKABLE : permet au métaobjet d'appeler la méthode ;
  • Q_SIGNAL : marque la méthode en tant que signal ;
  • Q_SLOT : marque la méthode en tant que slot.

Il est possible de déduire des informations de la documentation de Q_INVOKABLE que cette macro est uniquement conçue pour les méthodes. Il faut toutefois noter que seuls les constructeurs ayant été déclarés avec le modificateur Q_INVOKABLE sont rendus disponibles à travers le système de méta-objets. L'utilisation de Q_INVOKABLE n'est donc pas limitée aux méthodes.

Par exemple :

 
Sélectionnez
class MyWidget : public QWidget
{
    Q_OBJECT

    public:
    Q_INVOKABLE MyWidget(QObject *parent = 0); // Constructeur recensé
    void myFunction(); // Méthode non recensée
    Q_INVOKABLE void myOtherFunction(); // Méthode recensée
    Q_SLOT void mySlot(); // Slot recensé

    public slots:
    void myOtherSlot(); // Slot recensé
};
Créé le 7 mai 2012  par Louis du Verdier

Lien : Qu'est-ce que le moc ?

La principale raison de la présence du système de métaobjets est le besoin d'instaurer un mode de communication entre les objets, qu'ils aient ou non un lien entre eux. Autrement dit, le système de signaux et de slots est la principale cause de la présence du système de méta-objets dans le framework Qt. Cette raison fait d'ailleurs l'objet de critiques de la part de gens pensant que l'utilisation des templates serait plus appropriée pour gérer cela. La documentation répond d'ailleurs à ces critiques.

Le système de métaobjets est nécessaire aux dispositifs suivants :

  • le système de signaux et de slots, qui permet la communication entre des objets sans rapport particulier ;
  • l'introspection, soit la capacité d'un programme à analyser son état lors de l'exécution ;
  • le système de propriétés, un dispositif multiplateforme de gestion de valeurs avec au minimum une fonction de lecture.

Exemples de frameworks/autres s'appuyant en grande partie sur le système de métaobjets :

  • QtScript, qui permet de manipuler une instance de QObject par du JavaScript ;
  • QtAnimation, qui permet de modifier une propriété au fil du temps ;
  • QtStateMachine, qui permet de modifier une propriété ;
  • QML, qui permet de manipuler une instance de QObject.
Créé le 7 mai 2012  par Louis du Verdier

Lien : Pourquoi Qt n'utilise pas les templates pour les signaux et les slots ?

Le moc (meta-object compiler, compilateur de métaobjets en français) est utilisé dans une étape additionnelle de la compilation. Make se sert du moc lorsqu'il est appelé, mais celui-ci peut aussi être appelé manuellement. Tout dépend donc des besoins.

Le fonctionnement du moc est simple : il lit les fichiers source et retrouve les déclarations de classe où la macro Q_OBJECT est utilisée. Une fois cela terminé, il génère des fichiers, reconnaissables par leur nom sous la forme de moc_[Nom du fichier d'en-tête].cpp (dans le cas d'une utilisation de Q_OBJECT dans un fichier d'en-tête) ou bien sous la forme de [Nom du fichier].moc (dans le cas d'une utilisation de la macro sans fichier d'en-tête), qui contiendront le code de méta-objet par exemple nécessaire à l'utilisation des signaux et des slots.

Ce système possède tout de même des points faibles. Par exemple, il ne gère pas correctement les classes templates qui se voient donc être privées des signaux et des slots. La documentation détaille les limitations que cause le moc.

Créé le 7 mai 2012  par Louis du Verdier

Q_OBJECT est une macro qui permet à la classe la contenant dans sa section privée de posséder un métaobjet, à condition qu'elle hérite, directement ou non, de QObject. Si la classe n'hérite pas de QObject, utilisez Q_GADGET à la place de Q_OBJECT.

 
Sélectionnez
class MyWidget : public QWidget
{
    Q_OBJECT
    // ...
};

De nombreuses méthodes nécessitent la présence de la macro Q_OBJECT pour fonctionner correctement, et c'est pour cela qu'il est recommandé à plusieurs reprises par la documentation de l'utiliser « dans toutes les sous-classes de QObject sans prêter attention au fait qu'elles utilisent actuellement ou non les signaux, les slots et les propriétés ».

Créé le 7 mai 2012  par Louis du Verdier

Lien : De QObject aux métaobjets, une plongée au cœur des fondations de Qt

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 - 2017 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.