Partage
  • Partager sur Facebook
  • Partager sur Twitter

QSpinButton et signal valueChanged

Comment mieux contrôler ce signal

Sujet résolu
    1 septembre 2021 à 16:24:34

    Bonjour à tous, ma question sera peut-être plus de l'ordre de l'UX design parce que je suis pas sur qu'il y éxiste une pirouette pour résoudre mon soucis juste avec du code ...

    J'ai une Arduino qui active des électrodes suivant un cycle qui tourne en boucle

    Je créé un programme Qt qui permettra de renseigner le cycle à réaliser dans une UI et de télécharger ça dans l'Arduino pour paramétrer dynamiquement le cycle d'électrode (et comme ça les collègues qui ne savent pas / veulent pas coder une Arduino survivront quand je pars en vacances :D)

    Un cycle se décompose donc en plusieurs "step", j'ai une classe StepWidget et dans ma fenêtre principale j'ai un QSpinButton qui règle le nombre de StepWidget à afficher dans un QScrollArea

    Une petite image sera encore plus parlant :

    Ici le QSpinButton est réglé sur 12, j'ai donc 12 StepWidget numérotés de 1 à 12.

    Voici le slot qui me permet de modifier le nombre de StepWidget en fonction de la valeur du QSpinButton

    void MainWindow::on_nbStepSpinBox_valueChanged(int arg1)
    {
        auto currentNbStep = stepWidgetTab.count();
    
        // On créé ou supprime un à un des StepWidget tant que leur nombre ne correspond pas
        // à la valeur du QSpinButton
        while(currentNbStep != arg1) {
            if (currentNbStep < arg1) {
                StepWidget *temp = new StepWidget(currentNbStep + 1, ui->nbElectrodeSpinBox->value(), this);
    
                stepWidgetTab.push_back(temp);
                ui->stepWidgetLayout->insertWidget(currentNbStep, temp);
            }
    
            else {
                ui->stepWidgetLayout->removeWidget(stepWidgetTab.last());
                delete stepWidgetTab.last();
                stepWidgetTab.pop_back();
            }
    
            currentNbStep = stepWidgetTab.count();
        }
    }


    A vrai dire tout marche très bien pour le moment mais je me suis fait la réflexion suivante :

    Un utilisateur à déjà mis 12 StepWidget, pour chacun il s'est embêté à cocher les électrodes à activer à cette étape du cycle, il a rentré la durée en minutes et secondes de chaque étapes et là il se dit qu'en fait il lui faut 18 étapes pour faire son cycle.

    Pour aller plus vite au lieu de cliquer 6 fois sur la flêche du QSpinButton il décide de le modifer avec le clavier, il met son curseur dedans, supprime le '2' et le remplace par un '8'

    Avec mon code actuel, la suppression du '2' va changer la valeur contenue dans le QSpinButton, émettre le signal valueChanged avec comme paramètre '1' et donc ça va supprimer tous les widgets des étapes 2 à 12 ainsi que leurs réglages pour en faire réaparaitre 17 nouveaux quand il aura tapé son '8'. Tout le réglage qu'il aura fait sur les widgets Step 2 à Step 12 sera perdu et devra être refait 

    Je pourrais réimplémenter KeyPressEvent dans une classe dérivée de QSpinBox pour empêcher l'utilisateur de modifier la valeur au clavier mais si il doit faire un cycle de 30 étapes ça va pas l'amuser de cliquer 30 fois sur la flèche du QSpinBox donc j'aimerais éviter de faire ça 

    Je pourrais ajouter un bouton pour valider la valeur du QSpinBox avant d'update le nombre de StepWidget dans le QScrollArea mais c'est encore plus chiant pour l'utilisateur donc on oublie

    Je suis à la recherche d'une solution qui me permettrait de garder la possibilité de faire une saisie clavier de la valeur du QSpinBox mais qui ne supprimerait pas les données de certains widget lorsqu'on aurait une saisie de ce genre :

    12 -> 1 -> 18

    28 -> 2 -> 23

    Merci d'avance pour vos retours :)

    • Partager sur Facebook
    • Partager sur Twitter
      1 septembre 2021 à 16:45:48

      Pourquoi ne pas garder ces valeurs par devers l'IHM, même si elle ne sont pas "utiles" ?

      Passer de "12" à "1" puis à "18" fera que les 12 premiers ne changent pas et que les 13ème à 18ème éléments soient des clones du 12ème élément (ou du 1er, selon ce qui est le plus pratique pour le métier).

      Beaucoup d'IHM fonctionnent comme ceci et les utilisateurs finaux maîtrisent bien ce type de comportement "naturel".

      -
      Edité par bacelar 1 septembre 2021 à 16:46:23

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        1 septembre 2021 à 16:51:28

        Qu'est ce que tu entends par "garder ces valeurs par devers l'IHM" ?

        Les garder en mémoire dans une structure de données et les rechargées si le nombre de StepWidget diminue avant de réaugmenter ?

        Cacher les widget au lieu de les delete quand la valeur du SpinBox diminue ?

        Edit : Je ne sais pas si c'est très clair car dans le screen de mon premier message j'ai laissé toutes les tempo à 0 mais chaque step est susceptible d'avoir une tempo unique qui n'a rien à voir avec la tempo des précédents ou des suivants 

        "Cloner" le 1er widget ou le widget précédent lorsqu'on incrémente le SpinBox ne change rien au fait que si on décrémente le SpinBox je supprime le widget et on perd en même temps sa tempo unique déjà réglée

        -
        Edité par ThibaultVnt 1 septembre 2021 à 16:55:38

        • Partager sur Facebook
        • Partager sur Twitter
          1 septembre 2021 à 17:54:24

          Bon, on commence par les bases, ta couche d'IHM n'est pas ta couche métier, donc, au moins sur le papier, faire mumuse avec les boutons de l'IHM ne devrait pas impacter directement les valeurs utilisées par ta couche métier et donc encore moins ce que ta couche Data devrait retenir.

          Donc, si j'implémente une interface relou où il faut appuyer sur un bouton "save", mais qui à la bonne idée d'avoir un bouton "annuler", tu ferais comment pour implémenter ce machin ? (En implémentant un Design Pattern command peut-être ?)

          Et dans une interface un peu moins relou, avec un Ctrl-Z, par exemple ?

          Bin, c'est pas compliqué, il y a une liste de "step" configurés (c'est les step qui sont configurés), géré par la couche métier, et le nombre de "step" affiché/actifs courant, affiché par l'IHM mais toujours gérer par la couche métier (le nombre de step d'actif, le nombre de step affiché, ça c'est la tambouille de l'IHM). Le nombre de "step" configurés peut être différents du nombre de step actif.

          Quand la couche d'IHM indique une diminution du nombre de step actif, la couche métier en prend bien note mais ne supprime pas les informations des step déjà configurés. Quand l'interface indique une augmentation du nombre de step actif, la couche métier en prend bien note et utilise les step configurés, qui n'ont jamais été perdus, et si le nombre actif devient supérieur au nombre déjà configuré, il crée les manquant via du prototypage, du clonage d'élément déjà dans la liste (le premier, le dernier, etc...), ou via une méthode renseigné par l'utilisateur, le fichier de configuration, un pigeon voyageur entraîné à communiquer via une interface télépathique avec un bus logiciel New Age, etc...

          Le plus simple, c'est que tu demandes à un utilisateur "béta" (donc qui ne développe pas) de te dire comment l'interface devrait se comporter et pas implémenter un truc juste parce que c'est la manière la plus simple de l'implémenter (et encore, c'est largement faux).

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            2 septembre 2021 à 8:49:12

            D'accord je vois.

            En effet je n'ai pas convenablement séparé métier et IHM puisque ma MainWindow fait plus que juste l'affichage. C'est directement dans ma MainWindow que j'avais implémenté un QVector de StepWidget* dont le contenue était modifié directement par le SpinButton de l'IHM.

            Je vais implémenter une classe Controler, faire tous les signaux/slots/connects nécéssaire pour transmettre et traiter les ordres de l'IHM.

            Je note le sujet en résolu, j'ouvrirai un autre sujet si je bloque sur un point précis

            Merci pour tes conseils bonne journée

            • Partager sur Facebook
            • Partager sur Twitter

            QSpinButton et signal valueChanged

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            • Editeur
            • Markdown