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 :

Comment tracer une ligne à la souris


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de sebmag
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2009
    Messages : 52
    Par défaut Comment tracer une ligne à la souris
    Bonjour,

    Je me lance pour la première fois dans la conception d'un petit logiciel de dessin industriel ! Actuellement, j'en suis à l'étape où je souhaite tracer une ligne avec la souris.

    Voici ce que je souhaite faire :

    - Lors d'un premier clic, j'accroche la ligne à l'emplacement de la souris
    - j'étire la ligne jusqu'à un point de mon choix
    - je clic une seconde fois pour terminer la ligne.

    J'utilise une classe principale nommé "Dessin" qui hérite de QWidget, une qui hérite de QGraphicsView, une de QGraphicsScene et une de QGraphicsLineItem (pour la ligne à tracer).

    Le problème c'est que je ne sais pas du tout comment m'y prendre pour arriver au résultat souhaité !!!

    voici ma classe pour la ligne :
    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
    #include "ligne.h"
     
    Ligne::Ligne(QGraphicsItem *parent) :
            QGraphicsLineItem(parent)
    {
        acceptHoverEvents();
        setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
     
        m_pen.setWidth(1);
        m_pen.setColor(Qt::white);
        setPen(m_pen);
    }
    Ligne::Ligne(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent)
    {
        acceptHoverEvents();
        setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
     
        m_pen.setWidth(1);
        m_pen.setColor(Qt::white);
        setPen(m_pen);
     
        QGraphicsLineItem::QGraphicsLineItem(x1,y1,x2,y2,parent,0);
    }
     
    Ligne::~Ligne()
    {
     
    }
    Cette classe vous parait-elle correct ?
    Pourriez-vous me donner une piste ? Merci par avance !!!

  2. #2
    Membre éprouvé
    Avatar de GreatTux
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2009
    Messages : 77
    Par défaut
    Il faut que tu appelles le constructeur de la classe de base (QGraphicsLineItem) de la façon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Ligne::Ligne(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent)
        QGraphicsLineItem(x1,y1,x2,y2,parent,0)
    {
        acceptHoverEvents();
        setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
     
        m_pen.setWidth(1);
        m_pen.setColor(Qt::white);
        setPen(m_pen);
    }

  3. #3
    Membre confirmé Avatar de sebmag
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2009
    Messages : 52
    Par défaut
    merci GreatTux,

    Je viens de modifier !

    Il me reste à savoir comment procéder pour tracer ma ligne ! Je sais que je dois utiliser les évènements de la souris MouseMoveEvent, mousePresseEvent etc... mais je ne sais pas lesquels utiliser (ceux de la scene je suppose ?) et comment procéder pour mettre tout ça en place étape par étape (pour tracer la ligne).

    merci d'avance.

  4. #4
    Membre éprouvé
    Avatar de GreatTux
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2009
    Messages : 77
    Par défaut
    Si j'ai bien compris ton cas, il faudrait que tu dérives la classe QGraphicsView pour créer une classe perso. Dans cette classe, tu devras ensuite ré-implémenter la fonction suivante: http://qt.developpez.com/doc/4.6/qgr...ousepressevent afin de pouvoir gérer les clic de souris.

    Je pense que le plus simple est de gérer des états, pour la ligne tu en as deux. Un état "origine" et un état "ligne en cours de traçage". Deux états, donc tu peux utiliser un booléen. ça donnera qq chose comme:
    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
     
    if(!m_bTracageEnCours)
    {
       //ici tu traiteras le premier clique, càd tu récupères la 1ere coordonnée de la ligne
     
       //code...
     
       m_bTracageEnCours = true;
    }else
    {
      //ici tu traiteras le second clique, càd tu récupères la 2nd coodonnée
     
       //code...
     
       m_bTracageEnCours = false;
    }

  5. #5
    Membre confirmé Avatar de sebmag
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2009
    Messages : 52
    Par défaut
    Merci beaucoup,

    tu me retires une épine de plus !

    J'ai déjà dérivé cette classe et réimplémenté mousePressEvent(). Je ne savais pas que c'était dans cette classe que je pouvais gérer les clics de souris car j'ai aussi une classe dérivé de QGraphicsScene !

    Donc si j'ai bien compris, cette classe qui hérite de QGraphicsView va permettre de stocker (en quelque sorte) les coordonnées de ma ligne et de les envoyer à ma classe qui hérite de QGraphicsLineItem ?

    Et concernant l'affichage de la ligne, comment faire pour que la ligne reste afficher lors du déplacement de la souris ? Je pense à mouseMoveEvent() mais dans quelle classe l'utiliser et comment ?

    En fait, j'aimerais comprendre un peu le fonctionnement de tout ça !

    Encore merci.

  6. #6
    Membre confirmé Avatar de sebmag
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2009
    Messages : 52
    Par défaut
    En suivant tes conseils, j'ai réussi à tracer des lignes mais pas vraiment comme je l'attendais ! C'est quand même encourageant !!!

    Je n'arrive pas encore à garder la ligne à l'écran lorsque je l'étire !

    Actuellement, je clic une première fois pour accrocher la ligne, je déplace ma souris (et là, la ligne ne s'affiche pas ) et j'effectue un second clic pour que la ligne apparaisse enfin !

    Ce que je souhaite, c'est afficher cette ligne entre le premier point d'accrochage et le second point final lorsque je déplace ma souris !

    Je ne sais pas comment m'y prendre ! As-tu une idée ? Merci.

    Voici ce que j'ai fait dans ma classe QGraphicsScene :
    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
    Scene::Scene(QObject *parent) :
            QGraphicsScene(parent)
    {
        m_tracerEnCours = false;
    }
     
    Scene::~Scene()
    {
     
    }
     
    void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        int x = event->scenePos().x();
        int y = event->scenePos().y();
     
        emit coordScene(x,y);
     
        update();
        QGraphicsScene::mouseMoveEvent(event);
    }
     
    void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
     
        int x = event->scenePos().x();
        int y = event->scenePos().y();
     
        emit coordScenePress(x, y);
     
        if (!m_tracerEnCours)
        {
            m_coord1.setX(x);
            m_coord1.setY(y);
     
            m_tracerEnCours = true;
        }
        else
        {
            m_coord1.setX(x);
            m_coord1.setY(y);
     
            m_tracerEnCours = false;
        }
        update();
        QGraphicsScene::mousePressEvent(event);
    }
     
    QVector2D Scene::coordTrace1() const
    {
        QVector2D result = m_coord1;
     
        return result;
    }
     
    QVector2D Scene::coordTrace2() const
    {
        QVector2D result = m_coord2;
     
        return result;
    }
     
    bool Scene::clic() const
    {
        bool result = m_tracerEnCours;
     
        return result;
    }
    Puis la fonction dans la classe "Dessin" (hérite de QWidget) :

    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
    // Code...
    connect(m_scene,SIGNAL(coordScenePress(int,int)),this, SLOT(dessiner(int,int)));
    }
     
    void Dessin::dessiner(int x, int y)
    {
        if(ui->pushButtonLigne->isChecked())// Pour tracer une ligne
        {
            int x1=0;
            int y1=0;
            int x2=0;
            int y2=0;
     
                if(!m_scene->clic())
                {
                   x1 = m_scene->coordTrace1().x();
                   y1 = m_scene->coordTrace1().y();
     
                   Ligne *line = new Ligne(x1,y1,x,y);
                   m_scene->addItem(line);
                }
                else
                {
                    x2 = m_scene->coordTrace2().x();
                    y2 = m_scene->coordTrace2().y();
                    Ligne *line = new Ligne(x1,y1,x2,y2);
                    m_scene->addItem(line);
                }
        }
    }

  7. #7
    Membre confirmé Avatar de sebmag
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2009
    Messages : 52
    Par défaut
    Désolé de cette réponse plus que tardive ! Vacances obliges !

    J'ai donc suivis les conseils de GreatTux que je remercie au passage.

    Il fallait simplement ajouter une petite variable qui sert de repère lorsqu'une ligne est terminée !

    Voici le code :

    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
    void Dessin::dessiner(int x, int y)
    {
        m_vue->update();
        if(ui->pushButtonLigne->isChecked())// Pour tracer une ligne
        {
            int x1=0;
            int y1=0;
            int i=0;
     
            if(m_scene->clic())
            {  
                x1 = m_scene->coordTrace1().x();
                y1 = m_scene->coordTrace1().y();
     
                m_line->setLine(x1,y1,x,y);
            }
            else
            {
                x = m_scene->coordTrace2().x();
                y = m_scene->coordTrace2().y();
                i=1;
            }
     
            if (i==1)// Si la variable "i" vaut 1 à la fin d'une ligne : création d'une autre ligne etc...
            {
                m_line = new Ligne;
                m_scene->addItem(m_line);
            }
        }
    }
    Merci beaucoup de votre aide, ce sujet est résolu !

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/07/2011, 19h46
  2. Réponses: 8
    Dernier message: 05/10/2009, 18h46
  3. [TASM] Comment tracer une ligne ?
    Par taze1 dans le forum x86 16-bits
    Réponses: 4
    Dernier message: 08/05/2009, 19h02
  4. Réponses: 11
    Dernier message: 26/08/2007, 14h07
  5. Comment tracer une ligne verticale dans un graphique
    Par developpeur82 dans le forum MATLAB
    Réponses: 3
    Dernier message: 03/04/2007, 14h06

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