Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Qt] QML et C++

Anonyme
    14 août 2021 à 6:51:08

    Bonjour à tous,

    Je suis (enfin) passé au QML (impossible de faire des app android correctes en widget, le rendu n'a rien à voir)

    Par contre je veux rester au maximum en C++, le QML me servira uniquement pour le design

    Je sais qu'il y a différents posts qui traitent de la passerelle entre le C++ et le QML (et inversement) avec des méthodes plus ou moins complexes mais perso, je veux juste trouver un moyen de récupérer très simplement les éléments QML dans mon code C++ (par exemple retrouver un QPushButton via son 'id" et faire mes connexions et tout le rester en C++)... en espérant que ça ne fasse pas une machine à gaz lorsqu'il s'agira de menu déroulant avec 50 éléments dedans :D

    Vous pouvez m'éclairer svp?

    Merci d'avance :)

    -
    Edité par Anonyme 14 août 2021 à 7:30:51

    • Partager sur Facebook
    • Partager sur Twitter
      14 août 2021 à 8:17:22

      C'est possible de faire ca, mais c'est pas la bonne approche. En vrai, c'est même pas la bonne approche en C++, si ton but est par exemple d'avoir la partie métier de ton programme qui va chercher directement le bouton qui se trouve au fin fond de plusieurs couches d'UI. En faisant cela, tu casses la logique du découpage objet de l'UI.

      La bonne approche, dans tous les cas, est d'avoir un découpage logique cohérent du programme, en particulier en séparant la logique métier et la partie UI. Le principe de Demeter s'applique aussi pour les classes d'UI. Ensuite, on couple les 2 ensembles.

      Pour les widgets de Qt, l'approche classique est d'utiliser des QObject, des signaux et slots, et de connecter tout ça au niveau hiérarchique qui intègre les 2 parties.

      int main() {
          ...
          Metier m;
          UI ui;
          ...
          connect(&ui, &ui::signal, &m, &Metier::slot);
          ...
      }

      Pour le QML, la logique est assez proche, on expose avec qmlRegister les classes Qt dans le QML Engine et on les instancie avant de les utiliser. 

      Metier {
          id: m
      }
      
      UI {
          onSignal: m.slot();    
      }
      

      https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html#choosing-the-correct-integration-method-between-c-and-qml

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        14 août 2021 à 9:39:50

        Merci pour ta réponse!

        On est bien d'accord que la classe UI est la sheet qui gère la partie métier pour le coup?

        Car sinon c'est ce que je fais actuellement en mode QWidget

        Par exemple pour une classe "Employee", j'ai également une classe employee_UI qui contient tous les QObject associé à la page de l'employée et je les fais interagir entre eux (là dessus je pense qu'on est en phase...sinon j'ai pas tout compris ^^)

        PS: un truc que tu ne vas peut être pas aimer :D c'est que j'ai une structure "UI_collection" qui contient toutes mes UI, que je met dans ma classe "Application" et je les sors au besoin dans cette classe, par exemple:

        struct Sheets_Collection
        {
        
            //UI
            MainWindow_UI mainwindows_UI;
            Employees_UI employees_UI;
        
        };

        Ensuite, c'est dans ma classe Application que je fais toutes les connexions entres les différentes UI, et/ou qui va interagir sur ma classe Employee, mettre à jour un tableau se trouvant sur une autre UI etc etc (désolé je ne retrouve plus l'exemple qui j'avais fait mais tu comprends le principe?)

        Je m'en sors bien comme ça, mais je sais pas si c'est super propre

        Du coup, pour revenir au QML, je ne comprend toujours pas la logique pour faire la même chose sans faire de machine à gaz dans passer par une clase "Bridge" et des macros bizarre de Qt :(

        Pour faire simple, si j'ai:

        import QtQuick 2.15
        import QtQuick.Window 2.15
        import QtQuick.Controls 2.15
        import QtQuick.Layouts 1.0
        
        
        Window {
            id: window
            width: 640
            height: 480
            opacity: 1
            visible: true
            color: "#192086"
            title: qsTr("Hello World")
        
            TextInput {
                id: textInput
                x: 30
                y: 19
                width: 194
                height: 20
                text: qsTr("Text Input")
                anchors.verticalCenter: parent.verticalCenter
                font.pixelSize: 12
                horizontalAlignment: Text.AlignHCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
        


        Je veux juste pouvoir accéder à mon "textInput" dans mon code C++ (j'aurai un QML par sheet)

        -
        Edité par Anonyme 14 août 2021 à 9:44:01

        • Partager sur Facebook
        • Partager sur Twitter
          15 août 2021 à 1:23:20

          Asphodelus a écrit:

          On est bien d'accord que la classe UI est la sheet qui gère la partie métier pour le coup?

          Non, la partie métier est le traitement de tes données, c'est normalement séparé de la partie "présentation" (l'UI).

          Asphodelus a écrit:

          mais je sais pas si c'est super propre

          A priori, non.

          Mais ça sert à rien de s'attarder sur la bonne façon de faire les choses en QML alors. Ca va te sembler trop éloigné de ce que tu fais et tu ne vas pas comprendre.

          Du coup, pour faire les choses comme tu les as conçu, tu peux assigner une propriété au contexte : https://doc.qt.io/qt-6/qtqml-cppintegration-contextproperties.html , ou accéder a un objet avec son nom : https://doc.qt.io/qt-6/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name

          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            15 août 2021 à 6:16:50

            gbdivers a écrit:

            Asphodelus a écrit:

            On est bien d'accord que la classe UI est la sheet qui gère la partie métier pour le coup?

            Non, la partie métier est le traitement de tes données, c'est normalement séparé de la partie "présentation" (l'UI).


            Non mais je me suis mal expliqué je crois :)

            Si on prend l'exemple d'une gestion de stock, j'aurai bien ma classe "Stock" qui va gérer les manquants, les commandes à réaliser etc ET j'aurai ma classe "Stock_ui" qui va gérer la partie graphique, interactions etc

            En gros, je voulais savoir si ton code ci dessus était dans ce sens:

            int main() {
                ...
                Metier m;
                Metier_UI ui;
                ...
                connect(&ui, &ui::signal, &m, &Metier::slot);
                ...
            }



            Pour le reste, je vais jeter un oeil, merci :)

            -
            Edité par Anonyme 15 août 2021 à 6:18:58

            • Partager sur Facebook
            • Partager sur Twitter

            [Qt] QML et C++

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown