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 Discussion :

Formes graphiques cliquables


Sujet :

Qt

  1. #1
    Membre averti
    Avatar de Niak74
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 271
    Points : 333
    Points
    333
    Par défaut Formes graphiques cliquables
    Bonjour,

    Je vous expose mon problème actuel : Je souhaite créer des widgets personnalisés. La plupart seront dessinés par painting. Voici un exemple visuel de ce que je souhaite créer (sans le trait rouge) :




    Il s'agit d'un contrôleur de volume. Celui-ci sera utilisé dans un appareil portable doté d'un écran tactile. Le but voulu est de pouvoir régler le volume en "frottant" la zone de niveau de volume (leds vertes). On imagine que les voyants sont un ensemble de "boutons" qui modifient le niveau de volume. Il sera alors possible de maintenir le doigt appuyé à l'écran et glisser le long de l'indicateur pour diminuer ou augmenter le volume.

    Je suis à la recherche de moyens technique pour, d'une part, dessiner cette forme (je m'oriente vers l'utilisation de QPainter et de paintEvent()), et d'autre part, associer à certains éléments "dessinés" la détection du clic.

    En d'autres termes, je cherche un moyen de créer un bouton qui ne soit pas un QPushButton classique, rectangulaire.

    Avez-vous des idées?

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Points : 705
    Points
    705
    Par défaut
    Bonjour,

    Au vu de ce que tu dois faire, je te conseil de partir de la classe QWidget et de ré-implémenter un grand nombre de méthodes, entre autre les fonctions "event"...

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Regarde ceci
    http://qt.developpez.com/faq/?page=q...parence-widget
    il y as maintenant les sources

  4. #4
    Membre averti
    Avatar de Niak74
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 271
    Points : 333
    Points
    333
    Par défaut
    Intéressant, je vais jeter un œil à tout ça, merci !

  5. #5
    Membre averti
    Avatar de Niak74
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 271
    Points : 333
    Points
    333
    Par défaut
    Merci pour le coup de main !

    Finalement, j'ai opté pour un Widget à base de painting (sauf l'icone central qui est un QLabel). Pour gestion du clic, je travaille sur la position de la souris au moment du clic ou du déplacement.

    Pour ceux que ça pourrait intéresser, je mets un bout de code qui illustre la détection de la position de la souris dans un cercle inscrit dans un carré (la zone du widget). Il faut en effet passer par un changement de repère (du coin haut gauche de coordonnées (0.0) au centre du cercle/widget) et par une transformation de coordonnées cartésiennes à polaires.

    Widget.h :

    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
     
     
    class VolumeKnob : public QWidget
    {
        Q_OBJECT
     
    public:
        VolumeKnob(QWidget * parent, int initialVolume, bool muted);
     
    protected:
        void paintEvent(QPaintEvent *);
        void mousePressEvent(QMouseEvent*);
        void mouseMoveEvent(QMouseEvent*);
        void mouseReleaseEvent(QMouseEvent*);
     
    private:
        void analyzeMouseEvent(int mousePosX, int mousePosY, bool analyzeMuteClick, bool pressAction);
     
    private:
        QString m_volumeIconPath;
        QString m_volumeMutedIconPath;
        bool m_changingVolume;
        bool m_muted;
        int m_volumeLevel; //From 0 to 12
        QLabel * centerIcon;
     
    signals:
        void volumeMuted(bool);
        void volumeChanged(int); // percent 0-100
        void volumeSetted(); // percent
    };
    Widget.cpp :

    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
     
     
    (...)
     
    void VolumeKnob::analyzeMouseEvent(int mousePosX, int mousePosY, bool analyzeMuteClick, bool pressAction)
    {
        //Soit I le centre du widget
        //Soit M le point de click
     
        double xi = width()/2; //coordonnee en x de I dans le repere de base
        double yi = height()/2; //coordonnee en y de I dans le repere de base
     
        double xm = mousePosX; //coordonnee en x de M dans le repere de base
        double ym = mousePosY; //coordonnee en y de M dans le repere de base
     
        double xm_i = xm - xi; //coordonnee en x de M dans le repere orthonormal centre sur I
        double ym_i = ym - yi; //coordonnee en y de M dans le repere orthonormal centre sur I
     
        //Transformation en coordonnees polaires pour le point M
     
        double r = qSqrt( pow(xm_i,2) + pow(ym_i,2) ); //Rayon
        if(r == 0)
            return;
     
        double a; //Angle en radian
        if(xm_i > 0 && ym_i >= 0)
            a = atan(ym_i/xm_i);
        else if( xm_i > 0 && ym_i < 0)
            a = atan(ym_i/xm_i) + 2*PI;
        else if( xm_i < 0)
            a = atan(ym_i/xm_i) + PI;
        else if( xm_i == 0 && ym_i > 0)
            a = PI/2;
        else if( xm_i == 0 && ym_i < 0)
            a = 3 * PI / 2;
        double adeg = 180 * a / PI; //Angle en degre
     
        //Actions
     
        //Click au centre = mute
        if ( r < height()/6 )
        {
            if(analyzeMuteClick)
            {
                m_muted = !m_muted;
                repaint();
     
                emit volumeMuted(m_muted);
            }
            else
            {
                return;
            }
        }
        //Sinon = change volume
        else
        {
            if(pressAction)
                m_changingVolume = true;
     
            if(m_changingVolume)
            {
                //Zone vide
                if( adeg > 40 && adeg < 140 )
                    return;
     
                m_volumeLevel = (((int)adeg + 220)%360) / 20;
                repaint();
     
                emit volumeChanged(m_volumeLevel * 100 / 12); //Emet le niveau de volume en %
            }
        }
    }
     
    void VolumeKnob::mouseMoveEvent(QMouseEvent * event)
    {
        analyzeMouseEvent(event->x(), event->y(), false, false);
    }
     
    void VolumeKnob::mousePressEvent(QMouseEvent* event)
    {
        analyzeMouseEvent(event->x(), event->y(), true, true);
    }
     
    void VolumeKnob::mouseReleaseEvent(QMouseEvent* event)
    {
        if(m_changingVolume)
            emit volumeSetted();
     
        m_changingVolume = false;
    }

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

Discussions similaires

  1. Rafraichir forme graphique
    Par christof63 dans le forum MFC
    Réponses: 7
    Dernier message: 04/07/2008, 15h22
  2. Remplir des formes graphiques avec des motifs (quadrillage, ligne verticale, etc)
    Par La Piotte dans le forum Interfaces Graphiques en Java
    Réponses: 3
    Dernier message: 04/10/2007, 00h16
  3. Mise en forme graphique
    Par petitours dans le forum Access
    Réponses: 1
    Dernier message: 15/05/2006, 15h07
  4. Reprensenter JTree sous forme graphique
    Par tony_big_guy dans le forum Composants
    Réponses: 2
    Dernier message: 22/12/2005, 15h40
  5. Réponses: 4
    Dernier message: 09/03/2005, 17h15

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