QtCon, troisième journée
Intégration de CMake à Qt Creator, multifil avec Qt, une interface Qt Quick sans QML, un compte-rendu d'Arnold Dumas

Le , par arnolddumas, Rédacteur/Modérateur
« CMake in Qt Creator (and elsewhere) », par Thobias Hunger

CMake est très utilise dans le monde C++ ; malheureusement, il est assez complexe de développer autour, car il fonctionne comme une sorte de boite noire. On donne un CMakeLists.txt en entrée et on obtient un de Makefile ou fichier projet en sortie. Par contre, il est difficile d’accéder à la représentation en interne du projet, notamment pour les EDI.

Le but est de développer une sorte de serveur, à qui on pourrait envoyer des requêtes sur le projet en cours. Par exemple, demander la liste de fichiers pour la cible « mabibliotheque » ou encore « monbinaire ».

La communication se fait via un protocole JSON, lisible avec le module du même nom de Qt 5. Le projet est plus ou moins fonctionnel à l’heure actuelle. Une intégration upstream est en discussion mais risque de durer.

Des développeurs d’autres EDI, notamment Milian Wolff et Kevin Funk, tous les deux de KDevelop, étaient aussi là pour présenter leurs problématique, et s’assurer que ce serveur soit le plus générique possible.

« Multithreading with Qt », par Giuseppe D'Angelo

Cette présentation avait pour thème la parallélisation en C++ avec Qt :

  • QThread ;
  • synchronsation ;
  • thread safety avec Qt ;
  • Qt et STL concernant le multi-threading.


QThread hérite de QObject : il n’est donc ni copiable ni déplaçable, possède des signaux et des lots et est conçu pour gérer un fil d’exécution.

On peut créer un fil d’exécution avec ou sans boucle évènementielle. Si l'on ne souhaite pas de boucle événementielle, on peut simplement hériter de QThread et réimplémenter la méthode run(), on démarrera alors le fil d’exécution avec QThread::start(). Pour un QThread avec boucle événementielle, on appellera la methode QThread::exec(). On utilisera alors quit() ou exit() pour sortir du fil d’exécution. On peut modifier la priorité du fil d’exécution par la méthode setPriority(). Il est aussi possible d'utiliser une QEventLoop ou d'appeler directement QCoreApplication::processEvent().

C’est une mauvaise idée d'appeler sleep() au sein d'un fil d’exécution. Il vaut mieux tirer parti des signaux et slots (ou alors utiliser le polling).

Il n’est pas possible d’effectuer des opérations affectant l’IHM depuis un autre fil d’exécution que le principal. Impossible d’utiliser QWidget/Qt Quick/QPixmap hors du fil d’exécution principal. Par contre, ce n'est pas gênant d'utiliser des QImage/QPainter.

Concernant OpenGL, cela dépend de la configuration. La méthode QopenGLContext::supportThreadedOpenGL() permet de savoir si le multithread est géré.

Il faut faire attention à ne jamais bloquer le fil d’exécution principal, qui se trouve être responsable de l’IHM : ne pas appeler sleep(). Faire attention à supprimer tous les QObject d'un fil d’exécution avant de le supprimer.

Pour s’assurer de la suppression des QObject à la fin du fil d’exécution, on peut :

  • allouer les objets sur la pile ;
  • connecter deleteLater au signal QThread::finished() ;
  • déplacer les objets encore nécessaires dans le fil d’exécution principal (qApp->thread()).


Quand on parle de synchronisation, le mot-clé est : « data race ». Nécessite deux choses : au moins un des deux accès est une écriture et les accès ne sont pas atomiques, aucun accès n’ayant lieu avant l’autre.

Qt propose différentes classes pour synchroniser : QMutex, QSemaphore, QWaitCondition,, QReadWriteLock, QAtomicInt, QAtomicPointer<T>. Il y a aussi des classes RAII pour la gestion des verrous, comme QMutexLocker.

Une fonction est dite thread-safe si on peut appeler cette fonction au même moment, depuis différents fil d'exécution, sur les mêmes données, sans devoir synchroniser du côté développeur.

Réentrant : pareil que thread-safe mais sur des données différentes.
Non-réentrant (thread-unsafe) : fonction qui ne peut être appelée que depuis seul fil d’exécution à la fois.



Selon la documentation, QObject est réentrant mais, en pratique, cela est faux.



Alors, comment communiquer avec un QObject vivant dans une autre fil d’exécution ? Avec les connections multi-thread : QueuedConnection. Cela postera l'événement dans la boucle d’événement du fil d’exécution dans lequel vit le QObject receveur. L’objet receveur doit absolument vivre dans un fil d’exécution possédant une boucle d’événement. Les types passés en argument doivent être enregistrés via qRegisterMetaType.

Le type de la connexion est décidé uniquement au moment de l'émission du signal, sauf si le type est précisé lors de l'appel à QObject::connect().

Ce n'est pas un problème d’ajouter des signaux dans une sous-classe de QThread, mais ajouter des slots est le signe d'une mauvaise conception.

On peut sans souci combiner Qt et la bibliothèque standard (C++11) au niveau du multi-threading. Il est à noter que beaucoup d’outils peuvent vérifier le bon usage de l’API STL concernant le multithreading, mais ils ne fonctionnent pas avec Qt, à moins que l’implémentation de Qt ne repose sur la STL. QThread est plus pratique d’utilisation lorsque l'on travaille avec des QObjects.

À la fin de la session, les différents types venant de la STL et de Qt furent comparés.





« Making QML optional », par Andrew Knight

Problématique : les applications complexes reposant sur Qt Quick/QML rencontrent des problèmes de performances, de la lenteur, notamment au démarrage. En effet, tout le code QML doit être lu et compilé. L'idée de base est de prendre les classes de Qt Quick et de les exposer via une interface C++.

Le temps de création de la version C++ de l'interface est beaucoup plus rapide. Les temps de rendu sont les mêmes. Avec Qt Quick 1, la création de chaque bouton entraîne la création de nombreux QObject. Qt Quick 2 est bien plus efficace. L’implémentation maison ne nécessite qu'un seul QObject par bouton.

Discussion sur des classes permettant d'exposer des fonctions de dessin de bas niveau avec Qt Quick.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de arnolddumas arnolddumas - Rédacteur/Modérateur https://www.developpez.com
le 06/09/2016 à 16:46
Citation Envoyé par air-dex  Voir le message
En bref, les UWP de Windows 10 dépendent de Qt for WinRT. Du coup je les vois mal retirer "Qt for WinRT" de Qt dans un avenir proche. Je veux bien croire à l'arrêt du support de Windows (Phone) 8(.1) ainsi que de Windows RT, mais pas à l'arrêt pur et simple de "Qt for WinRT", et donc des UWP par voie de conséquence.

De ce que j'ai compris, cela est du au projet ANGLE (conversion des appels OpenGL en appels DirectX).

Le passage est disponible (35:37) : https://live.dus.c3voc.de/relive//qtcon16/354/muxed.mp4

Citation Envoyé par mintho carmo  Voir le message
Merci pour les comptes rendus.

Les videos sont deja dispo : http://streaming.media.ccc.de/qtcon16/relive/ (je ne sais pas trop c'est quoi ce site, mais les videos devrait probablement etre dispo aussi sur la chaine youtube de Qt plus tard)

Il avait malheureusement fallu attendre des mois pour les précédentes éditions des Qt Developer Days.

PS : c'est le site du Chaos Computer Club, très réputé en Europe germanophone, notamment pour l'organisation du Chaos Communication Congress.
Avatar de air-dex air-dex - Membre émérite https://www.developpez.com
le 07/09/2016 à 2:05
Citation Envoyé par arnolddumas  Voir le message
« Making QML optional », par Andrew Knight

Problématique : les applications complexes reposant sur Qt Quick/QML rencontrent des problèmes de performances, de la lenteur, notamment au démarrage. En effet, tout le code QML doit être lu et compilé. L'idée de base est de prendre les classes de Qt Quick et de les exposer via une interface C++.

Le temps de création de la version C++ de l'interface est beaucoup plus rapide. Les temps de rendu sont les mêmes. Avec Qt Quick 1, la création de chaque bouton entraîne la création de nombreux QObject. Qt Quick 2 est bien plus efficace. L’implémentation maison ne nécessite qu'un seul QObject par bouton.

Discussion sur des classes permettant d'exposer des fonctions de dessin de bas niveau avec Qt Quick.

Personnellement j'ai toujours trouvé ça dégueulasse de manipuler du QML côté C++. Il me semble plus lisible et compréhensible d'exposer et d'utiliser des interfaces C++/QML dans le code QML (via des joyeusetés comme qmlRegisterType(); dans le main();) plutôt que d'aller directement attaquer le composant QML je ne sais où côté C++ (avec des joyeusetés comme QQmlEngine, QQmlContext et autres QQmlComponent). Certes c'est moins performant, mais si les performances sont (très) importantes alors autant faire du 100% C++ avec ce bon vieux Qt Widgets, non ?
Avatar de arnolddumas arnolddumas - Rédacteur/Modérateur https://www.developpez.com
le 07/09/2016 à 8:27
De ce qu'il a été présenté, il s'agissait plus de prouver la faisabilité et de mesurer les performances que de vraiment développer une technologie aboutie. De l'avis meme du presentateur, les chiffres ne sont pas forcement fiables car mesurant parfois des choses différentes, de plus, son implémentation reposait sur une version ancienne de Qt (quelque chose comme 5.4 si je me souviens bien).
Offres d'emploi IT
Développeur Web FULL-STACK
VACALIANS GROUP - Languedoc Roussillon - SETE (34)
Développeur WEB PHP F/H
VACALIANS GROUP - Languedoc Roussillon - SETE (34)
RESPONSABLE WEB ANALYTICS F/H
VACALIANS GROUP - Languedoc Roussillon - SETE (34)

Voir plus d'offres Voir la carte des offres IT
Responsable bénévole de la rubrique Qt : Thibaut Cuvelier -