Porter une application de Qt 1.0 à Qt 5.11 ? Un jeu d'enfant !
Un développeur de Qt s'amuse à porter le tutoriel de l'époque

Le , par dourouc05, Responsable Qt & Livres
Avec la récente sortie de Qt 5.11 et les vingt-deux ans du projet Qt, un développeur de Qt a décidé de voir à quel point il était difficile de porter une application Qt 1.0 (une version de Qt qui date de 1996 !) vers 5.11. Le tutoriel, qui vise à réaliser un petit jeu de tir au canon (d’ailleurs traduit en français), a servi de cobaye pour cette petite expérience.


Qt a une politique très précise en ce qui concerne la compatibilité tant des sources que des binaires : pour mettre à une jour la version de Qt, il ne faut pas même pas la recompiler (sauf pour une nouvelle version majeure) ! (La compatibilité binaire descendante n’est cependant pas garantie : pour utiliser une plus vieille version de Qt, l’idéal est de la recompiler.) En même temps, la compatibilité des sources ne peut être cassée que lors d’une version majeure. Même dans ce cas, l’objectif des développeurs est de limiter la casse, en n’effectuant que les modifications nécessaires à l’amélioration du framework. Sur les vingt-deux ans d’existence de Qt, cette compatibilité n’a été cassée que quatre fois : en 1999 avec Qt 2.0, en 2001 avec Qt 3.0, en 2005 avec Qt 4.0, en 2012 (!) avec Qt 5.0. De manière générale, seule la transition entre Qt 3 et 4 a posé de véritables problèmes généralisés.

Quelles modifications a-t-il fallu réaliser pour porter cette petite application de dix fichiers et presque huit cents lignes ?

  • Avec Qt 1.0, il n’y avait pas qmake, mais seulement tmake, un script Perl peu fiable. La syntaxe des fichiers de projet était très similaire… à une exception notable : il était permis d’écrire du code Perl dans ces fichiers pour adapter finement la compilation. Avec qmake, bon nombre de limitations de tmake ont été levées et cette possibilité n’était plus requise : qmake est prévu pour être utilisé par le plus grand nombre, tmake n’était utilisé que pour Qt.

  • Quelques fichiers d’en-tête ont changé de nom. En effet, dans les années 1990, certaines versions de Windows ne permettaient que huit caractères dans le nom de fichier (plus trois pour l’extension). Il fallait donc écrire des noms horribles comme “qbttngrp” au lieu de “qbuttongroup”. De plus, l’exemple exploitait énormément les inclusions indirectes, qui ont été limitées avec les versions ultérieures de Qt.

  • Avec Qt 1.0, le langage C++ était très loin de son état actuel. Notamment, il n’y avait même pas de type de booléen, qui a dû être codé dans Qt.

  • Toujours pour des raisons historiques, bon nombre de valeurs constantes ne pouvaient pas être mises dans un espace de noms, pour la simple et bonne raison qu’ils n’étaient pas gérés par la majorité des compilateurs.

  • Auparavant, les QObject disposaient d’un nom donné lors de leur construction. Maintenant, ces noms sont facultatifs.

  • L’API de QScrollBar a énormément changé : au lieu d’un constructeur à sept arguments (la majorité numériques), il faut maintenant utiliser des mutateurs bien plus précis.

  • Aux débuts de Qt, Unicode n’était pas exactement à la mode et QString correspondait exactement à const char *, ce qui n’est plus le cas.

  • Certains identifiants, comme warning(), n’avaient pas de préfixe Q.
  • Aussi, en 1996, la plupart des écrans ne gérait que deux cent cinquante-six couleurs, il fallait que l’application en demande plus pour qu’elles soient disponibles.

  • QAccel était un mauvais choix de nom (une abréviation assez barbare), QShortcut en a aussi facilité l’utilisation.

  • La manière de dessiner à l’écran a aussi bien changé : il n’est plus possible de dessiner directement sur un widget, il faut passer par des tampons et des demandes de mise à jour.

  • QObject::killTimers() était l’une des pires idées possibles : cette fonction supprimait tous les minuteurs associés à un objet, y compris ceux utilisés en interne par Qt. Il faut désormais spécifier exactement lequel on souhaite supprimer.

  • La couleur d’arrière-plan n’est plus gérée de manière distincte d’une palette de couleur.

  • Qt 4 a apporté une incompatibilité assez majeure, puisque le code précédent compile toujours, mais est devenu faux : QPainter::drawRect() dessine un rectangle en incluant la taille du pinceau (qui ne l’était pas auparavant).

  • Finalement, pour améliorer le rendu, on peut ajouter une disposition pour que les éléments se mettent à la bonne taille automatiquement. La classe QLayout n’est arrivée qu’avec Qt 1.1…


En conclusion ? Il reste assez facile de porter une très vieille application vers la toute dernière version de Qt. Les applications réelles poseront probablement d’autres problèmes à cause de changements apportés dans d’autres parties de Qt, mais l’opération reste possible.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Responsable bénévole de la rubrique Qt : Thibaut Cuvelier -