IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Quick Discussion :

Lier des boutons entre eux (comme des boutons radio) [Débuter]


Sujet :

Qt Quick

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut Lier des boutons entre eux (comme des boutons radio)
    Bonjour,

    Je cherche à faire un menu en qml avec des boutons qui restent activés une fois cliqués. Et une fois qu'on clique sur un autre bouton, le premier activé se désactive. Un peu à la manière des radiobuttons.

    Pour le moment j'ai un élément BoutonPanneau possédant 2 états: Activé et Neutre. Chaque bouton passe d'un état à l'autre à chaque clic indépendamment des autres boutons. Mon but maintenant est de les rendre solidaires, mais là est le problème, je ne sais pas comment faire.

    J'avais pensé envoyer un signal "Désactivation" renvoyant tous les boutons à l'état neutre et réactiver le bouton cliqué. Mais je ne sais pas comment interagir avec un signal émit par un élément frère.

    Merci de votre aide.

    Cordialement

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    Hello,

    Il faut utiliser un QButtonGroup.

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        QButtonGroup *group = new QButtonGroup;
        QPushButton *button1 = new QPushButton("Bt 1");
        button1->setCheckable(true);
        button1->setChecked(true);
        QPushButton *button2 = new QPushButton("Bt 2");
        button2->setCheckable(true);
        QPushButton *button3 = new QPushButton("Bt 3");
        button3->setCheckable(true);
        group->addButton(button1, 1);
        group->addButton(button2, 2);
        group->addButton(button3, 3);

    Edit: Arf c'est en Qml, du coup c'est n'est pas cela... toutes mes excuses...

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    L'équivalent en Qml s'appelle ExclusiveGroup

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     import QtQuick 2.2
    import QtQuick.Window 2.1
    import QtQuick.Controls 1.2
     
    Window {
        visible: true
        width: 360
        height: 360
     
        ExclusiveGroup{
            id: exGroup
        }
     
        Row{
            Button{
                text: "button1"
                checkable: true
                checked: true
                exclusiveGroup: exGroup
            }
            Button{
                text: "button2"
                checkable: true
                exclusiveGroup: exGroup
            }
            Button{
                text: "button3"
                checkable: true
                exclusiveGroup: exGroup
            }
        }  
    }
    Edit:
    Pour ajouter le support d'ExclusiveGroup dans un item personnalisé, voici un code exemple tiré de la doc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Item {
        id: myItem
     
        property bool checked: false
        property ExclusiveGroup exclusiveGroup: null
     
        onExclusiveGroupChanged{
            if (exclusiveGroup)
                exclusiveGroup.bindCheckable(myItem)
        }
    }

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Merci, je vais regarder ça pour l'adapter aux états de mes boutons. C'est bien ce que j'avais vu pour les radioboutons mais j'étais pas sûr de mon coup.

    Cordialement

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Quoique je fasse, j'ai toujours un résultat un peu bizarre. Par exemple, deux boutons sont checkables une fois et c'est tout. Je comprend pas comment ça marche. Je vous met mon code, des fois que vous y voyiez des erreurs. Mais j'ai suivi la documentation à la lettre.

    D'abord, le panneau qui contient les boutons
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    import QtQuick 2.0
    import QtQuick.Window 2.0
    import QtQuick.Controls 1.2
     
    Window {
        id:demandeChemin
        width:1200
        height:800
        minimumHeight:height
        minimumWidth:width
        maximumHeight:height
        maximumWidth:width
        visible:true
        Image{
            anchors.fill:parent
            source: "../images/configuration1.jpg"
        }
     
        Rectangle{
          id:panneauLateral
          height:parent.height
          width:400
          color:"#010d23"
          opacity:0.7
          anchors.left:parent.left
          anchors.top:parent.top
        }
     
        ExclusiveGroup{
              id: exGroup
          }
        Column{
        BoutonPanneau{
            id:boutonSelectionChemin
            text: "TEST"
            width : 400
            height : 50
            fontSize : 12
            checked: false
            exclusiveGroup: exGroup
        }
        BoutonPanneau{
            id:boutontest1
            text: "TEST1"
            width : 400
            height : 50
            fontSize : 12
            checked: true
            exclusiveGroup: exGroup
        }
        BoutonPanneau{
            id:boutontest2
            text: "TEST2"
            width : 400
            height : 50
            fontSize : 12
            checked: false
            exclusiveGroup: exGroup
        }
    }
     
    }
    Et voila le code des boutons
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    import QtQuick 2.0
    import QtQuick.Controls 1.2
     
    Item{
        id: container
        property alias text : label.text
        property alias fontSize : label.font.pointSize
        property ExclusiveGroup exclusiveGroup: null
        property bool checked
        signal clicked
        signal entered
        state:"Neutre"
        onExclusiveGroupChanged{
                if (exclusiveGroup)
                    exclusiveGroup.bindCheckable(container)
            }
     
    Rectangle {
        id:fond
       opacity:container.opacity
       border.width: 1
       height:parent.height
       width:parent.width
       smooth: true //pour avoir une meilleure qualité visuelle
     
     
       SystemPalette { id: activePalette }
     
       MouseArea {
         id: mouseArea
         anchors.fill: parent
         onClicked{container.clicked();
          if (container.checked)
          {
              container.checked==false
              container.state='Neutre'
          }
          else
          {   container.checked==true
              container.state='Actif'}
         }
         onEntered: container.entered()
       }
     
       gradient: Gradient {
        GradientStop {
         id: grad1
         position: 0.0
         color: "white"
        }
     
        GradientStop {
         id: grad2
         position: 0.25
         color: "#010d23"
        }
     
        GradientStop {
         id: grad3
         position: 0.75
         color: "#010d23"
        }
     
        GradientStop {
         id: grad4
         position: 1.0
         color: "white"
        }
      }
     
    }
    Text  {
        id : label
        anchors.centerIn: fond
        text : ""
        color : !mouseArea.pressed ? "white":"#999a9f"
    }
     
    states: [
     
        State {
            name: "Actif"
            PropertyChanges { target: grad1; color: "#010d23" }
            PropertyChanges { target: grad4; color: "#010d23" }
        },
        State {
            name: "Neutre"
            PropertyChanges { target: grad1; color: "white" }
            PropertyChanges { target: grad4; color: "white" }
        }
    ]
    }
    Cordialement

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    Hello,

    Effectivement je vois une erreur, l'utilisation de l'opérateur == qui est une condition:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //il faut remplacer
    container.checked==false
    //par
    container.checked=false
    sinon, pour te simplifier la vie, tu peux utiliser la propriété "when" de l'élément "State" afin de changer "automatiquement" d'état lorsque la propriété checked change.

    Je remet le code complet, j'ai fait 2 ou 3 modifs, mais rien de très important, mis à part la changement de == en = .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    import QtQuick 2.0
    import QtQuick.Controls 1.1
     
    Item{
        id: container
        property alias text : label.text
        property alias fontSize : label.font.pointSize
        property ExclusiveGroup exclusiveGroup: null
        //il est bien de s'habituer à initialiser les
        //proprietés, comme ça on est sûre de l'état
        //initial de notre composant
        property bool checked: false
        signal clicked
        signal entered
        state:"Neutre"
        onExclusiveGroupChanged{
            if (exclusiveGroup)
                exclusiveGroup.bindCheckable(container)
        }
     
        Rectangle {
            id:fond
            opacity:container.opacity
            border.width: 1
            height:parent.height
            width:parent.width
            smooth: true //pour avoir une meilleure qualité visuelle
     
            SystemPalette { id: activePalette }
     
            MouseArea {
                id: mouseArea
                anchors.fill: parent
                onClicked{container.clicked();
                    if (container.checked)
                    {
                        container.checked=false
                        //container.state="Neutre"
                        console.log(text + "state changed to Neutre");
                    }
                    else
                    {   container.checked=true
                        //container.state="Actif"
                        console.log(text + "state changed to Actif");
                    }
                }
                onEntered: container.entered()
            }
     
            gradient: Gradient {
                GradientStop {
                    id: grad1
                    position: 0.0
                    color: "white"
                }
     
                GradientStop {
                    id: grad2
                    position: 0.25
                    color: "#010d23"
                }
     
                GradientStop {
                    id: grad3
                    position: 0.75
                    color: "#010d23"
                }
     
                GradientStop {
                    id: grad4
                    position: 1.0
                    color: "white"
                }
            }
     
        }
        Text  {
            id : label
            anchors.centerIn: fond
            text : ""
            color : !mouseArea.pressed ? "white":"#999a9f"
        }
     
        states: [
     
            State {
                when: container.checked
                name: "Actif"
                PropertyChanges { target: grad1; color: "#010d23" }
                PropertyChanges { target: grad4; color: "#010d23" }
            },
            State {
                //when: !checked //pas nécessaire
                name: "Neutre"
                PropertyChanges { target: grad1; color: "white" }
                PropertyChanges { target: grad4; color: "white" }
            }
        ]
    }
    Ah oui, un petit commentaire. Afin de rendre le bouton réutilisable dans d'autre circonstances, il serait pas mal d'ajouter une propriété "checkable". Mais si c'est seulement pour un usage unique. ce n'est pas nécessaire.

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Oui c'est pour un usage unique. J'ai testé le code, ça marche à peu près. Je m'explique:
    Quand un bouton est actif, je peux toujours activer les autres. Pour les activer, je dois cliquer deux fois dessus. Moi je pensais que le conteneur faisait en sorte que garder un seul élément actif. Quel est le vrai impact du ExclusiveGroup? Je veux dire par là, à quoi sert-il? Pour le moment, j'ai l'impression qu'il n'a aucun impact.

  8. #8
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    Bizarre, chez moi ça fonctionne bien...

  9. #9
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    Essaye d'utiliser les messages avec console.log("message") afin de t'aider à déboguer.

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    C'est bon ça marche, j'avais pas vu la ligne when: container.checked dans le code à rajouter.
    Merci de votre aide

    Cordialement

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 218
    Points : 55
    Points
    55
    Par défaut
    Petit problème que j'ai noté par contre: tous les boutons peuvent être inactifs si j'appuie sur celui qui est actif. Il suffit alors de remplacer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
         onClicked{container.clicked();
          if (container.checked)
          {
              container.checked=false
              console.log(text + "state changed to Neutre");
          }
          else
          {   container.checked=true
              console.log(text + "state changed to Actif");}
         }
         onEntered: container.entered()
       }
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!container.checked) {container.checked=true}
    La propriété checked est automatiquement passée à false lorsqu'on clique sur un autre élément. Par contre l'inverse est faux (je ne sais pas pourquoi). En enlevant complètement le if, la propriété checked ne passe jamais à true.

    Cordialement

  12. #12
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut
    J’aurais pensé que l'EclusiveGroup empêcherait cela. Mais c'est bien au composant utilisant le groupe exclusif de vérifier cela.
    J'ai jeté un œil au code source de l'élément Button.qml fourni par Qt pour en être sûre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function toggle() {
                //C'est cette condition "!(button.checked && button.exclusiveGroup)" qui permet 
                //au bouton de ne pas se désactiver lorsqu'il appartient à un groupe exclusif          
                if (button.checkable && !button.action && !(button.checked && button.exclusiveGroup))
                    button.checked = !button.checked
            }
    La propriété checked est automatiquement passée à false lorsqu'on clique sur un autre élément. Par contre l'inverse est faux (je ne sais pas pourquoi). En enlevant complètement le if, la propriété checked ne passe jamais à true.
    la propriété est passé à false par l'ExclusiveGroup, grâce à la liaison crée avec exclusiveGroup.bindCheckable(container). C'est justement son rôle. Lorsque la propriété checked d'un des boutons passe à true, il désactive tout autre bouton qui serait déjà activé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lier des objets entre eux !
    Par laurent94 dans le forum Powerpoint
    Réponses: 4
    Dernier message: 26/05/2015, 03h05
  2. Archivage : Lier des documents entre-eux
    Par _Em'' dans le forum Configuration
    Réponses: 2
    Dernier message: 06/11/2012, 16h41
  3. Taille des composants entre eux ?
    Par Pasokoniidesuka dans le forum Débuter
    Réponses: 5
    Dernier message: 04/02/2011, 03h28
  4. Réponses: 0
    Dernier message: 10/04/2010, 01h40
  5. connecter des objets entre eux
    Par etienne.clopeau dans le forum Général Python
    Réponses: 6
    Dernier message: 10/02/2010, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo