L'art d'un guerrier est de maintenir l'équilibre
entre l'horreur d'être humain et le miracle d'être humain.
"Voyage à Ixtlan"Mon chemin de guerrier - un développeur frontend brutal sur les pros - était de trouver un équilibre entre le développement d'une application qui fonctionne sur Sailfish et une application multiplateforme.
Récemment, j'ai travaillé sur le poste de développeur chez Digital Design, et parfois je dois faire face à des tâches que je n'avais pas rencontrées auparavant. C'est intéressant et souvent amusant. Maintenant, par exemple, j'écris une application d'entreprise pour Sailfish OS et je veux partager mon expérience avec vous - cela sera discuté ci-dessous. Suivez-moi sous la coupe, si vous êtes un développeur débutant ou, tout comme moi, confronté à la tâche d'adapter une application d'entreprise pour OS Sailfish et ne savez pas par où commencer, ainsi que ceux qui n'ont pas entendu parler des fonctionnalités de Qt et Sailfish.
Un peu d'histoire, ou pourquoi je l'ai fait
Lorsque la société a développé la solution Areopad ISCO pour iPad (iOS) il y a 5 ans, personne ne pouvait penser que les clients auraient besoin d'une application pour travailler sur un appareil avec Sailfish OS (alors l'OS appartenait à la société finlandaise Jolla, cependant, maintenant aussi). Mais en 2016, la société russe Open Mobile Platform a acquis une licence pour son utilisation, sa modification, sa distribution et l'a évoquée: elle a adapté les appareils mobiles et les utilisateurs nationaux (principalement des entreprises et des organismes gouvernementaux) et a enregistré Sailfish Mobile OS RUS
dans le registre . Et maintenant, on pourrait dire que c'est le seul système d'exploitation russe officiel pour les appareils mobiles.
Naturellement, nous voulions le comprendre - nous avons déjà conquis le reste du système d'exploitation, et Sailfish, apparemment, a un grand avenir (oui, je parle de substitution des importations). De tout cela, il s'ensuit que la demande pour Sailfish soit! La première application à être testée a été l'application mobile Système d'information pour le travail des instances collégiales Areopad (elle n'en était qu'au stade de la modernisation).
Maintenant sur qt
Un merveilleux outil multiplateforme qui comprend un environnement de développement, une tonne de bibliothèques utiles et pratiques, et même votre propre langage de balisage QML. Je ne m'y attarderai pas longtemps, car de nombreux articles ont été écrits sur ce miracle sur l'Habré, et vous pouvez également lire la
documentation , qui se lit facilement et naturellement.
Juste au cas où, je préciserai que les calculs et le mappage ont lieu dans différents langages dans différents modules (C ++ et QML) qui interagissent les uns avec les autres en utilisant des méthodes délicates spéciales (propriété, signal-slot).
Et Qt est le cadre principal utilisé dans le développement de logiciels pour Sailfish.
Approches pour résoudre le problème: allez à gauche - vous gagnerez une béquille, allez à droite - vous perdrez des fonctionnalités
Au début, inspiré par l'idée de multiplateforme et par le fait que je vais l'implémenter, je pensais qu'une application écrite pour Sailfish ne décollerait pas, mais flopperait volontiers sur n'importe quel autre OS, même un réfrigérateur ou une bouilloire. Mais mon bonheur a duré exactement jusqu'au moment où je me suis assis pour l'exécuter sur Android - puis je me suis senti triste. Sailfish n'est pas du tout adapté à cette activité et n'a nullement l'intention de changer quoi que ce soit.
Si Android ou iOS vous permettent d'utiliser la compilation conditionnelle et de fournir une sorte de boîte à outils pour cela, Sailfish ne peut pas être distingué de Linux (dans Qt, bien sûr).
Ensuite, le problème de compatibilité QML se pose: dans Sailfish, la version obsolète de Qt Quick (2.6 pour Sailfish et déjà 2.11 pour tout le monde), Android ne connaît pas Silica, Sailfish ne connaît pas QtQuick.Controls. Par conséquent, pour différents systèmes d'exploitation, vous devez extraire les mêmes composants de différentes bibliothèques, ce qui produit presque les mêmes fichiers pour chaque système d'exploitation.
Dans le même temps, Silica possède probablement toutes les mêmes fonctionnalités que QtQuick.Controls, mais refuse de s'exécuter sur toute autre plate-forme.
Caractéristiques Sailfish
Étant une personne créative
paresseuse, aussi créative que possible avec le désir d'optimiser les coûts de main-d'œuvre, j'ai pris le chemin de la moindre
résistance fonctionnelle et j'ai écrit mon chef-d'œuvre en Qt pur, sans utiliser QtQuick.Controls et Silica. En conséquence, tout fonctionne correctement et noblement sur Sailfish, mais sur Android, la moitié des éléments, malgré mon ordre strict de rester immobile, sont allés quelque part pour leurs questions probablement importantes, donc la prochaine étape sera toujours faite chez un adulte et divorcé fichiers de balisage pour chaque système d'exploitation sous différents angles. [Ce que j'ai fait plus tard, en préparant un article pour publication. Cette histoire s'appuie sur un article séparé]. N'oubliez pas et acceptez: les constantes magiques sont mauvaises (par exemple, largeur: 15). Et sur deux appareils presque identiques, même avec le même OS, ils peuvent différer de 2 fois.
Cependant, je ne peux que noter qu'il y a certainement des choses intéressantes dans la version Sailfish. Bien sûr, pendant une si courte période que je le connais, il est presque impossible de connaître tout le monde intérieur riche de Sailfish - notre relation avec lui est au stade de la "période du bouquet de bonbons", et une grande partie de ce que je n'ai pas encore étudiée dans son caractère complexe. De plus, il a été décidé de dessiner une application universelle pour tous les systèmes d'exploitation, donc je n'ai pas eu la chance d'utiliser des mécanismes plus sophistiqués pour utiliser cette chance, mais je vais probablement vous parler de quelques points intéressants.
Nous ne parlerons que d'une seule bibliothèque pour implémenter l'interface graphique Silica, car le reste que j'ai réussi à apprendre et à comprendre n'est pas différent de la programmation QML standard.
Cet outil m'a le plus intéressé parce que je n'ai pas vu d'analogue dans d'autres systèmes d'exploitation, et il est également simple. L'essentiel est que la conception de l'application n'est pas une constante, mais dépend du sujet choisi.
L'élément de thème contient des informations sur le sujet actuellement sélectionné: couleurs primaires, tailles de police, retraits et composants. Ainsi, lorsque vous écrivez des applications, vous n'avez pas besoin de coder en dur les couleurs, d'ajuster la taille pour s'adapter à l'écran et de regarder généralement la mise en page (pardonnez aux concepteurs, vous avez déjà beaucoup de travail), vous pouvez simplement tout tirer de l'élément Thème. Eh bien, n'est-ce pas cool!

Aussi une fonctionnalité de Sailfish (bien que cela puisse être possible dans Android, mais je ne l'ai pas vu).
Il existe trois types de menus:
PullDownMenu - PushUpMenu - ContextMenu


Quant à Silica ... View - ils ne diffèrent pas de la vue standard ... View (ce sont ± quelques propriétés peu visibles), et le composant Button vous rend assez nerveux - la hauteur du bouton ne peut pas être modifiée, vous devez écrire Rectangle et MouseArea partout. Si je faisais une application pour Sailfish uniquement, en utilisant la conception standard de ce système d'exploitation, il ne serait pas nécessaire de modifier la hauteur du bouton ou il serait possible d'utiliser un
composant de Silica . Mais comme j'écris une application pour tous les appareils, il a été décidé d'utiliser le design le plus massif (Android), pour que tout le monde soit familier et confortable. Beaucoup sont en désaccord avec moi et disent que vous devez utiliser des éléments d'interface utilisateur natifs pour chaque plate-forme, mais c'est un sujet complètement différent, il fait l'objet d'holivars depuis de nombreuses années, pendant cette période, plus d'une génération de développeurs a grandi.
Volez dans la pommade vers le développement mobile sur Qt
Dans Qt, pour communiquer avec le serveur, appeler une fonction ne suffit pas, vous devez envoyer une demande et demander à un objet spécial responsable de la réponse du serveur d'appeler la fonction de traitement des réponses (qui, bien sûr, nous nous écrivons) lorsque la réponse est reçue:
void foo() { QNetworkRequest request("http://www.leningrad.spb.ru"); QNetworkReply *reply = mngr->get(request); connect(reply, &QNetworkReply::finished, this, &Class:: onReplyFinished); } void onReplyFinished () { QNetworkReply *reply = (QNetworkReply*)sender(); QByteArray ans = reply->readAll(); qDebug() << ans; }
La fonction onRhnessFinished sera appelée lorsqu'une réponse est reçue du serveur, et cela peut prendre peu importe combien de temps cela dépend de la qualité de la connexion et du côté serveur. Imaginez maintenant comment tout cela sera organisé avec 1500 à 2000 requêtes, qui dans ce cas dépendent les unes des autres et doivent être exécutées dans un ordre strict. Et si vous vous souvenez que toute la partie de l'interface utilisateur dépend de la réponse, cela devient complètement effrayant.
- Programmation orientée béquille ou approche créative pour résoudre les problèmes
Un autre sujet est ListView, qui est un problème Qt très local, mais toujours désagréable.
Tout ListView qui se respecte doit avoir un composant d'en-tête qui, en tant que premier délégué, insère un élément fondamentalement différent du reste. Oui, il le fait, oui, il peint tout parfaitement, si ce n'était pas pour un "mais": mon délégué occupe tout l'écran, et il faut le faire défiler, mais dès que j'essaie de faire défiler vers la gauche vers l'en-tête à partir de l'index zéro, il refuse fondamentalement cela afficher l'en-tête. Que faire à ce sujet? Remplissez avec une béquille. Un morceau de mon code de formation de modèle pour ce ListView dans la partie cpp, qui décrit ce qui se passe aussi précisément que possible:
foreach (QVariant quest, QQuestions) { Questions.append(new Question(client, quest)); } kostilQuestions = Questions; if (Questions.size() > 0) kostilQuestions.prepend(Questions[0]);
Ensuite, 2 éléments indépendants sont créés dans le délégué, dont la visibilité dépend de l'index.
Lorsque l'indice est nul, on en voit un, sinon l'autre.
Résumé
En conséquence, j'ai obtenu une application qui "vole" à la fois sur Android et iOS, et Sailfish, plus précisément une application flexible qui s'adapte à ces systèmes d'exploitation. Et la magie n'a rien à voir avec ça. J'ai trouvé un moyen d'éviter les conflits et de faire des amis tous les OS avec Sailfish en substituant certains fichiers à Sailfish et à tout le monde. Cela nous a permis de sélectionner des couches d'interface utilisateur pour chaque système d'exploitation dans le code d'application.
Nous pouvons supposer que nous avons fait le premier pas - nous nous sommes liés d'amitié avec Sailfish. Mais le travail à ce sujet n'est pas terminé, Sailfish et moi allons à un nouveau niveau de notre relation - nous préparons la demande Areopad CSIS pour l'enregistrement dans le registre (comme l'application Sailfish), ce qui signifie que nous devrons l'adapter également pour le registre.
J'espère que c'était intéressant. À suivre.