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

Interfaces Graphiques Discussion :

Afficher deux curseurs sous forme de lignes verticales sur un graphe


Sujet :

Interfaces Graphiques

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut Afficher deux curseurs sous forme de lignes verticales sur un graphe
    Bonjour à tous,

    Histoire de passer le temps, je me suis lancé dans la conception d'un script qui me permettrait à terme d'ouvrir un fichier texte à partir d'une interface graphique et d'y tracer un graphe à partir des données qui s'y trouvent afin de déterminer des délais à l'aide de deux curseurs qui se présenteraient sous la forme de lignes verticales.

    Je planche pour le moment sur l'affichage de ces deux curseurs.

    J'ai trouvé sur mathworks.com un script gentillement proposé par un certain Jiro Doke (à cette adresse, un grand merci à lui d'ailleurs) qui permet l'affichage d'un curseur vertical. J'ai tenté quelques modifications pour afficher un deuxième curseur mais sans succès. L'idée est de pouvoir afficher et manipuler (par manipuler j'entends déplacer de gauche à droite) le premier curseur (nommé A) à l'aide du clic gauche souris et le second curseur (nommé B) à l'aide du clic droit. Je n'obtiens en revanche toujours qu'un seul curseur. Je pense que le problème se situe au niveau de ma fonction dragFcn et notamment de la récupération de la position du pointeur souris.

    Je vous mets en copie le script original, ainsi que celui comportant mes quelques modestes modifications.

    Original par Jiro Doke :
    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
    function vertical_cursors
     
    set(gcf, ...
       'WindowButtonDownFcn', @clickFcn, ...
       'WindowButtonUpFcn', @unclickFcn);
     
    % Set up cursor text
    allLines = findobj(gcf, 'type', 'line');
    hText = nan(1, length(allLines));
    for id = 1:length(allLines)
       hText(id) = text(NaN, NaN, '', ...
          'Parent', get(allLines(id), 'Parent'), ...
          'BackgroundColor', 'yellow', ...
          'Color', get(allLines(id), 'Color'));
    end
     
    % Set up cursor lines
    allAxes = findobj(gcf, 'Type', 'axes');
    hCur = nan(1, length(allAxes));
    for id = 1:length(allAxes)
       hCur(id) = line([NaN NaN], ylim(allAxes(id)), ...
          'Color', 'black', 'Parent', allAxes(id));
    end
     
         function clickFcn(varargin)
            % Initiate cursor if clicked anywhere but the figure
            if strcmpi(get(gco, 'type'), 'figure')
               set(hCur, 'XData', [NaN NaN]);                % <-- EDIT
               set(hText, 'Position', [NaN NaN]);            % <-- EDIT
            else
               set(gcf, 'WindowButtonMotionFcn', @dragFcn)
               dragFcn()
            end
         end
     
         function dragFcn(varargin)
            % Get mouse location
            pt = get(gca, 'CurrentPoint');
     
            % Update cursor line position
            set(hCur, 'XData', [pt(1), pt(1)]);
     
            % Update cursor text
            for idx = 1:length(allLines)
               xdata = get(allLines(idx), 'XData');
               ydata = get(allLines(idx), 'YData');
               if pt(1) >= xdata(1) && pt(1) <= xdata(end)
                  y = interp1(xdata, ydata, pt(1));
                  set(hText(idx), 'Position', [pt(1), y], ...
                     'String', sprintf('(%0.2f, %0.2f)', pt(1), y));
               else
                  set(hText(idx), 'Position', [NaN NaN]);
               end
            end
     
         end
     
         function unclickFcn(varargin)
            set(gcf, 'WindowButtonMotionFcn', '');
         end
     
    end
    La version modifiée :
    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
    function vertical_cursors
     
    set(gcf, ...
       'WindowButtonDownFcn', @clickFcn, ...
       'WindowButtonUpFcn', @unclickFcn);
     
    % Set up cursor text
    allLines = findobj(gcf, 'type', 'line');
    hTextA = nan(1, length(allLines));
    hTextB = nan(1, length(allLines));
     
    for id = 1:length(allLines)
       hTextA(id) = text(NaN, NaN, '', ...
          'Parent', get(allLines(id), 'Parent'), ...
          'BackgroundColor', 'yellow', ...
          'Color', get(allLines(id), 'Color'));
     
       hTextB(id) = text(NaN, NaN, '', ...
          'Parent', get(allLines(id), 'Parent'), ...
          'BackgroundColor', 'yellow', ...
          'Color', get(allLines(id), 'Color'));
    end
     
    % Set up cursor lines
    allAxes = findobj(gcf, 'Type', 'axes');
    hCurA = nan(1, length(allAxes));
    hCurB = nan(1, length(allAxes));
     
    for id = 1:length(allAxes)
       hCurA(id) = line([NaN NaN], ylim(allAxes(id)), ...
          'Color', 'black', 'Parent', allAxes(id));
     
       hCurB(id) = line([NaN NaN], ylim(allAxes(id)), ...
          'Color', 'black', 'Parent', allAxes(id));
    end
     
         function clickFcn(varargin)
            % Curseur A clic gauche
             if strcmpi(get(gcf,'SelectionType'),'normal')
                 if strcmpi(get(gco, 'type'), 'figure')
    %                 set(hCurA, 'XData', [NaN NaN]);                
    %                 set(hTextA, 'Position', [NaN NaN]);            
                 else
                    set(gcf, 'WindowButtonMotionFcn', @dragFcn)
                    dragFcn()
                 end
             % Curseur B clic droit
             elseif strcmpi(get(gcf,'SelectionType'),'alt')
                 if strcmpi(get(gco, 'type'), 'figure')
    %                 set(hCurB, 'XData', [NaN NaN]);                
    %                 set(hTextB, 'Position', [NaN NaN]);            
                 else
                    set(gcf, 'WindowButtonMotionFcn', @dragFcn)
                    dragFcn()
                 end
             end
         end
     
         function dragFcn(varargin)
             % Get mouse location
             pt = get(gca, 'CurrentPoint');
     
             % Update cursor line position
             set(hCurA, 'XData', [pt(1), pt(1)]);
             set(hCurB, 'XData', [pt(1), pt(1)]);
     
             % Update cursor text
             for idx = 1:length(allLines)
                 xdata = get(allLines(idx), 'XData');
                 ydata = get(allLines(idx), 'YData');
     
                if pt(1) >= xdata(1) && pt(1) <= xdata(end)
                   y = interp1(xdata, ydata, pt(1));
                   set(hTextA(idx), 'Position', [pt(1), y], ...
                      'String', sprintf('(%0.2f, %0.2f)', pt(1), y));
     
                   set(hTextB(idx), 'Position', [pt(1), y], ...
                      'String', sprintf('(%0.2f, %0.2f)', pt(1), y));
                else
                   set(hTextA(idx), 'Position', [NaN NaN]);
                   set(hTextB(idx), 'Position', [NaN NaN]);
                end
             end
         end
     
         function unclickFcn(varargin)
            set(gcf, 'WindowButtonMotionFcn', '');
         end
     
    end
    Un rapide graphe sur lequel la fonction peut être testée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x = 0:0.1:10;
    plot(x,cos(x));
    Merci d'avance pour votre aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    J'avais posté plusieurs variantes d'une solution (avec commentaires) dans cette discussion
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  3. #3
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Merci beaucoup Dut, tes propositions ainsi que les commentaires associés m'ont bien aidé à éclaircir quelques points noirs.

    J'ai ainsi opté pour l'une de tes solutions, moyennant quelques changements.

    Parmi ceux-ci, j'aimerais pouvoir sortir à la fois l'abscisse du curseur mais aussi l'ordonnée de la courbe à cette abscisse. Je suis parti sur l'idée du script que j'ai posté plus tôt, à savoir une interpolation mais celle-ci me renvoie le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Error using griddedInterpolant
    Interpolation requires at least two sample points in each dimension.
    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    function Curseur
     
    % Ouverture d'une fenetre
    fig = figure('Doublebuffer','On');
     
     
    % Un tracé
    th =linspace(0,4*pi,200);
    fth = sin(th);
    plot(th,fth,'r');
     
     
    % Récuperation des limites du graphique
    x = xlim;
    y = ylim;
     
     
    % Ajout des deux curseurs et prise en compte du clic souris 
    % avec la propriété ButtonDownFcn
    hCurA = line([0.1*x(2) 0.1*x(2)],y,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
    hCurB = line([0.2*x(2) 0.2*x(2)],y,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
    % Curseurs invisibles au lancement
    % set(hCurA,'Visible','Off');
    % set(hCurB,'Visible','Off');
     
     
    % Pour afficher/supprimer curseurs
    pushbuttonCurseurOn = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.0285 0.936 0.175 0.0458],...
        'string','Curseur on',...
        'tag','pushCurseurOn',...
        'callback',@CurseurOn,...
        'backgroundcolor',get(fig,'color'));
     
    pushbuttonCurseurOff = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.285 0.936 0.175 0.0458],...
        'string','Curseur off',...
        'tag','pushCurseurOff',...
        'callback',@CurseurOff,...
        'backgroundcolor',get(fig,'color'));
     
     
    % Blocage des limites du graphique
    set(gca,'Xlimmode','Manu');
     
     
    % Textblock pour affichage abs+ord
    hTextA = text(0,0,...
        sprintf('(%0.2f, %0.2f)',0,0),...
        'BackgroundColor','Yellow',...
        'Color',get(hCurA,'Color'));
     
     
        function clickFcn(obj,event)
            % Fonction a exécuter quand on clique sur une barre
            % OBJ : identifiant de la barre sélectionnée
            % WindowButtonMotionFcn : fonction à exécuter quand on déplace la souris
            % WindowButtonUpFcn : fonction à exécuter quand on relâche la souris
            set(fig,'WindowButtonMotionFcn',{@dragFcn,obj},  ...
                'WindowButtonUpFcn',@unclickFcn);
        end
     
        function dragFcn(obj,event,h)
            % Fonction à exécuter quand on déplace la souris
            % OBJ : identifiant de la fenetre courante
            % H : identifiant de la barre sélectionnée
     
            % Modification du pointeur de la souris (juste esthétique)
            set(fig,'Pointer','Fleur');
            % Récupération des coordonnées du pointeur de la souris
            pt = get(gca,'CurrentPoint');
            % Modification de la position en x de la barre sélectionnée
            set(h,'Xdata',[pt(1),pt(1)]);
     
            % Maj textbox avec position curseur
            xdata = get(hCurA,'XData');
            ydata = get(hCurA,'YData');
     
            % Determination ordonnees
            pt(1) >= xdata(1) && pt(1) <= xdata(2);
            u = interp1(xdata, ydata,pt(1));
     
            set(hTextA,'Position',[xdata(2),u],...
                'String',sprintf('(%0.2f, %0.2f)',xdata(2),u)); 
        end
     
        function unclickFcn(obj,event)
            % Fonction à exécuter quand on relâche la souris
            set(fig,'WindowButtonMotionFcn',[],'Pointer','Arrow');
        end
     
        function CurseurOn(obj,event)
            % Callback pushbutton pour affichage curseurs
            set(hCurA,'Visible','On'); 
            set(hCurB,'Visible','On'); 
        end
     
        function CurseurOff(obj,event)
            % Callback pushbutton pour suppression curseurs
            set(hCurA,'Visible','Off'); 
            set(hCurB,'Visible','Off'); 
        end
     
    end

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    hCurA ne représente que le handle de la ligne verticale, donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            xdata = get(hCurA,'XData');
            ydata = get(hCurA,'YData');
    ne récupère que ses deux points.
    Toi tu souhaites plutôt utiliser les coordonnées de ta sinusoïde :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    u = interp1(th, fth, pt(1));
    Remarque : cette ligne ne fait rien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            pt(1) >= xdata(1) && pt(1) <= xdata(2);

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Merci beaucoup Jerome.

    J'ai maintenant mes deux curseurs, les deux textbox associées ainsi que le calcul et l'affichage du délai selon x. J'aimerais afficher de la même façon le délai selon y. Je pensais récupérer la valeur y de chaque textbox avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    get(handles.tag_de_la_textbox,'string')
    mais mes textbox ne sont pas des structures.

    J'ai tenté de les transformer en uicontrol à la manière de mes pushbutton mais la position nécessite alors quatre coordonnées, ce qui me complique un peu la tâche par la suite.

    J'aimerais également profiter du pushbutton qui permet de supprimer les curseurs pour également réinitialiser leur position. J'ai testé avec la propriété 'Position' mais matlab me renvoie qu'elle n'est pas accessible pour les lignes.

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    function en_travaux
     
    % Ouverture d'une fenetre
    fig = figure('Doublebuffer','On');
     
     
    % Un tracé
    th =linspace(0,4*pi,200);
    fth = sin(th);
    plot(th,fth,'r');
     
     
    % Récuperation des limites du graphique
    a = xlim;
    b = ylim;
     
     
    % Ajout des deux curseurs et prise en compte du clic souris 
    % avec la propriété ButtonDownFcn
    hCurA = line([0.1*a(2) 0.1*a(2)],b,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
    hCurB = line([0.2*a(2) 0.2*a(2)],b,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
     
    % Curseurs invisibles au lancement
    % set(hCurA,'Visible','Off');
    % set(hCurB,'Visible','Off');
     
     
    pushbuttonCurseurOn = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.0285 0.936 0.175 0.0458],...
        'string','Curseur on',...
        'tag','pushCurseurOn',...
        'callback',@CurseurOn,...
        'backgroundcolor',get(fig,'color'));
     
     
    pushbuttonCurseurOff = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.285 0.936 0.175 0.0458],...
        'string','Curseur off',...
        'tag','pushCurseurOff',...
        'callback',@CurseurOff,...
        'backgroundcolor',get(fig,'color'));
     
     
    deltaXtext = uicontrol(fig,...
        'style','text',...
        'units','normalized',...
        'position',[0.585 0.936 0.175 0.0458],...
        'string','',...
        'backgroundcolor',get(fig,'color'));
     
     
    % Blocage des limites du graphique
    set(gca,'Xlimmode','Manu');
     
     
    % Creation textbox
    hTextA = text(NaN,NaN,'',...
        'Tag','hTextA',...
        'BackgroundColor','Yellow',...
        'Color',get(hCurA,'Color'));
     
    hTextB = text(NaN,NaN,'',...
        'Tag','hTextB',...
        'BackgroundColor','Yellow',...
        'Color',get(hCurB,'Color'));
     
     
    % Definition des fonctions 
        function clickFcn(obj,event)
            % Fonction a exécuter quand on clique sur une barre
            % OBJ : identifiant de la barre sélectionnée
            % WindowButtonMotionFcn : fonction à exécuter au drag souris
            % WindowButtonUpFcn : fonction à exécuter au relachmt souris
            set(fig,'WindowButtonMotionFcn',{@dragFcn,obj},  ...
                'WindowButtonUpFcn',@unclickFcn);
        end
     
     
        function dragFcn(obj,event,h)
            % Fonction à exécuter quand on déplace la souris
            % OBJ : identifiant de la fenetre courante
            % H : identifiant de la barre sélectionnée
     
            % Modification du pointeur de la souris (juste esthétique)
            set(fig,'Pointer','Fleur');
            % Récupération des coordonnées du pointeur de la souris
            pt = get(gca,'CurrentPoint');
            % Modification de la position en x de la barre sélectionnée
            set(h,'Xdata',[pt(1),pt(1)]);
     
            % Maj textbox avec position curseur A
            xdataA = get(hCurA,'XData');
     
            % Maj textbox avec position curseur B
            xdataB = get(hCurB,'XData');
     
            % Interpolation y au pointeur souris
            y = interp1(th,fth,pt(1));
     
            % Affichage coordonnees
            if pt(1) == xdataA(2)
                set(hTextA,'Position',[xdataA(2),y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataA(2),y)); 
            elseif pt(1) == xdataB(2)
                set(hTextB,'Position',[xdataB(2),y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataB(2),y)); 
            end
     
            % Affichage delta
            deltaX = abs(xdataB(2) - xdataA(2));
            set(deltaXtext,'string',sprintf('%0.2f',deltaX));  
        end
     
     
        function unclickFcn(obj,event)
            % Fonction à exécuter quand on relâche la souris
            set(fig,'WindowButtonMotionFcn',[],'Pointer','Arrow');
        end
     
     
        function CurseurOn(obj,event)
            % Callback pushbutton pour affichage curseurs
            set(hCurA,'Visible','On'); 
            set(hCurB,'Visible','On');
     
            set(hTextA,'Visible','On'); 
            set(hTextB,'Visible','On');             
        end
     
     
        function CurseurOff(obj,event)
            % Callback pushbutton pour suppression curseurs
            set(hCurA,'Visible','Off'); 
            set(hCurB,'Visible','Off');
     
            set(hTextA,'Visible','Off'); 
            set(hTextB,'Visible','Off');         
        end
     
    end

  6. #6
    Invité
    Invité(e)
    Par défaut
    handles.tag_de_l_objet est la syntaxe usuelle utilisée avec l'outil GUIDE. Elle permet de retrouver le handle de l'objet en question. La structure handles est passée en argument supplémentaire des fonctions callback.
    Tu peux si tu le souhaites récupérer cette même structure par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    handles = guihandles(fig);
    une fois tous tes objets créés.
    Mais tu peux ici utiliser directement hText obtenu par hText = text( ... );.

    Pour ton dernier problème, ce n'est pas 'Position' mais 'Xdata' qu'il faut modifier, comme tu le fais déjà dans dragFcn.

  7. #7
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Impeccable, merci une nouvelle fois Jerome. La réinitialisation des curseurs après un clic sur un pushbutton fonctionne bien. J'avoue ne pas avoir pensé à réutiliser 'XData'.

    J'ai également réussi à récupérer les positions y de mes deux curseurs. C'est pas très sexy mais ça fonctionne, c'est déjà ça. En revanche, je bute sur le calcul du delta y. Les deux variables yA et yB n'existent pas toujours, surtout à l'affichage initial des curseurs, pas moyen donc de calculer leur différence en tout temps. J'ai donc rajouté une condition avec isempty sur yA et yB. Dans l'absolu, ça devrait fonctionner mais je n'arrive pas à voir pourquoi ce n'est pas le cas.

    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
            yA = [];
            yB = [];
     
            if pt(1) == xdataA(2)
                set(hTextA,'Position',[xdataA(2) y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataA(2),y)); 
     
                TextA = get(hTextA,'String');
                [~,yA] = strread(TextA,'%s %s','delimiter',', ');
                yA = str2double(strrep(yA{1},')',''));
     
            elseif pt(1) == xdataB(2)
                set(hTextB,'Position',[xdataB(2) y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataB(2),y)); 
     
                TextB = get(hTextB,'String');
                [~,yB] = strread(TextB,'%s %s','delimiter',', ');
                yB = str2double(strrep(yB{1},')','')); 
            end
     
            % Affichage delta
            deltaX = abs(xdataB(2) - xdataA(2));
            set(deltaXtext,'string',sprintf('%0.2f',deltaX));  
     
            if ~isempty(yA) && ~isempty(yB)
                deltaY = abs(yB - yA)
                set(deltaYtext,'string',sprintf('%0.2f',deltaY));  
            end

  8. #8
    Invité
    Invité(e)
    Par défaut
    Parce que tu as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    yA = [];
    yB = [];
    if ...
        % tu fixes yA
    else if ...
        % tu fixes yB
    end
    if ~isempty(yA) && ~isempty(yB)
        ...
    end
    Tu fixes donc soit yA, soit yB, mais jamais les deux.

    Le plus simple serait de définir yA et yB vides dans la fonction mère au lieu de dragFcn.

    Aussi, à la place des deux conditions if/else if précédentes, tu peux vérifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if h == hCurA 
        ...
    else if h == hCurB

  9. #9
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Merci beaucoup pour ton aide Jerome !

    La fonction pour les intéressés qui passeraient par là :

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    function curs_vert
     
    % Ouverture d'une fenetre
    fig = figure('Doublebuffer','On');
     
     
    % Un tracé
    th =linspace(0,4*pi,200);
    fth = sin(th);
    plot(th,fth,'r');
     
     
    % Récuperation des limites du graphique
    a = xlim;
    b = ylim;
     
     
    % Ajout des deux curseurs et prise en compte du clic souris 
    % avec la propriété ButtonDownFcn
    hCurA = line([0.1*a(2) 0.1*a(2)],b,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
    hCurB = line([0.2*a(2) 0.2*a(2)],b,'Linewidth',1,...
        'Color','Black','ButtonDownFcn',@clickFcn);
     
     
    % Curseurs invisibles au lancement
    set(hCurA,'Visible','Off');
    set(hCurB,'Visible','Off');
     
     
    % Creation des pushbutton
    pushbuttonCurseurOn = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.0285 0.936 0.175 0.0458],...
        'string','Curseur on',...
        'tag','pushCurseurOn',...
        'callback',@CurseurOn,...
        'backgroundcolor',get(fig,'color'));
     
    pushbuttonCurseurOff = uicontrol(fig,...
        'style','pushbutton',...
        'units','normalized',...
        'position',[0.285 0.936 0.175 0.0458],...
        'string','Curseur off',...
        'tag','pushCurseurOff',...
        'callback',@CurseurOff,...
        'backgroundcolor',get(fig,'color'));
     
     
    % Creation des editbox
    deltaXtext = uicontrol(fig,...
        'style','text',...
        'units','normalized',...
        'position',[0.585 0.936 0.175 0.0458],...
        'string','0',...
        'backgroundcolor',get(fig,'color'));
     
    deltaYtext = uicontrol(fig,...
        'style','text',...
        'units','normalized',...
        'position',[0.785 0.936 0.175 0.0458],...
        'string','0',...
        'backgroundcolor',get(fig,'color'));
     
     
    % Creation des textbox
    hTextA = text(NaN,NaN,'',...
        'Tag','hTextA',...
        'BackgroundColor','Yellow',...
        'Color',get(hCurA,'Color'));
     
    hTextB = text(NaN,NaN,'',...
        'Tag','hTextB',...
        'BackgroundColor','Yellow',...
        'Color',get(hCurB,'Color'));
     
     
    % Blocage des limites du graphique
    set(gca,'Xlimmode','Manu');
     
     
    % Coordonnees yA et yB vides au demarrage
    yA = [];
    yB = [];
     
     
    % Definition des fonctions 
        function clickFcn(obj,event)
            % Fonction a exécuter quand on clique sur une barre
            % OBJ : identifiant de la barre sélectionnée
            % WindowButtonMotionFcn : fonction à exécuter au drag souris
            % WindowButtonUpFcn : fonction à exécuter au relachmt souris
            set(fig,'WindowButtonMotionFcn',{@dragFcn,obj},  ...
                'WindowButtonUpFcn',@unclickFcn);
        end
     
     
        function dragFcn(obj,event,h)
            % Fonction à exécuter quand on déplace la souris
            % OBJ : identifiant de la fenetre courante
            % H : identifiant de la barre sélectionnée
     
            % Modification du pointeur de la souris (juste esthétique)
            set(fig,'Pointer','Fleur');
            % Récupération des coordonnées du pointeur de la souris
            pt = get(gca,'CurrentPoint');
            % Modification de la position en x de la barre sélectionnée
            set(h,'Xdata',[pt(1),pt(1)]);
     
            % Maj textbox avec position curseur A
            xdataA = get(hCurA,'XData');
     
            % Maj textbox avec position curseur B
            xdataB = get(hCurB,'XData');
     
            % Interpolation y au pointeur souris
            y = interp1(th,fth,pt(1));
     
            % Affichage coordonnees dans textbox curseur A
            if h == hCurA
                set(hTextA,'Position',[xdataA(2) y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataA(2),y)); 
     
                TextA = get(hTextA,'String');
                [~,yA] = strread(TextA,'%s %s','delimiter',', ');
                yA = str2double(strrep(yA{1},')',''));
     
            % Affichage coordonnees dans textbox curseur B
            elseif h == hCurB
                set(hTextB,'Position',[xdataB(2) y],...
                    'String',sprintf('(%0.2f, %0.2f)',xdataB(2),y)); 
     
                TextB = get(hTextB,'String');
                [~,yB] = strread(TextB,'%s %s','delimiter',', ');
                yB = str2double(strrep(yB{1},')','')); 
            end
     
            % Affichage des differences entre coordonnees
            deltaX = abs(xdataB(2) - xdataA(2));
            set(deltaXtext,'String',sprintf('%0.2f',deltaX));  
     
            if ~isempty(yA) && ~isempty(yB)
                deltaY = abs(yB - yA);
                set(deltaYtext,'String',sprintf('%0.2f',deltaY));  
            end
        end
     
     
        function unclickFcn(obj,event)
            % Fonction à exécuter quand on relâche la souris
            set(fig,'WindowButtonMotionFcn',[],'Pointer','Arrow');
        end
     
     
        function CurseurOn(obj,event)
            % Callback pushbutton pour affichage et reset curseurs
            set(hCurA,'XData',[0.1*a(2) 0.1*a(2)],...
                'Visible','On'); 
            set(hCurB,'XData',[0.2*a(2) 0.2*a(2)],...
                'Visible','On');
     
            set(hTextA,'Position',[NaN NaN],...
                'Visible','On'); 
            set(hTextB,'Position',[NaN NaN],...
                'Visible','On');             
        end
     
     
        function CurseurOff(obj,event,h)
            % Callback pushbutton pour suppression curseurs
            set(hCurA,'Visible','Off'); 
            set(hCurB,'Visible','Off');
     
            set(hTextA,'Visible','Off'); 
            set(hTextB,'Visible','Off');
        end
     
    end

  10. #10
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Re-bonjour !

    Je me permets de ré-ouvrir cette discussion.

    J'essaye actuellement d'intégrer ce "module" de curseurs dans une interface graphique qui permet à l'utilisateur de sélectionner un fichier texte contenant X lignes d'entêtes et Y colonnes, de renseigner le nombre de ligne d'entêtes, le nombre de colonnes et ensuite de le charger. Le chargement du fichier permet ensuite à l'utilisateur de choisir quelle colonne il souhaite tracer en abscisses, et quelle colonne il souhaite tracer en ordonnées. Tout fonctionne correctement à l'exception de deux petites choses.

    La première concerne le calcul sur le delta en Y. Afin de calculer ce delta, j'ai eu besoin de définir yA et yB comme deux variables vides.
    Elles sont ensuite enregistrées via un setappdata puis appelées dans ma fonction dragFcn par un getappdata. Le souci est que, lors de la sélection et du glissement du curseur B, la valeur de yA est vidée et vice versa, la faute, je pense, à l'appel de yA et yB via getappdata en début de fonction. Seulement, le calcul du delta Y se fait seulement si les deux valeurs d'ordonnées sont non vides, d'où la nécessite d'initialiser mes variables quelque part. C'est justement ce quelque part que je n'arrive pas à déterminer.

    Le deuxième souci est moins problématique. J'essaye tant bien que mal d'empêcher l'utilisateur de charger le fichier si ce dernier n'est pas sélectionné (s'il est sélectionné, son nom est affiché dans l'editbox correspondante) et si le nombre de lignes d'entête et le nombre de colonnes ne sont pas renseignés. En clair, si trois de mes editbox ne sont pas renseignées, le pushbutton n'est pas cliquable. C'est l'objet de cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if ~isempty(get(handles.NomFich,'Value')) &&...
            ~isempty(get(handles.editNbHdL,'Value')) &&...
            ~isempty(get(handles.editNbCol,'Value'))
         set(handles.pushCharger,'Enable','on');
    end
    Mais dès lors que je sélectionne le fichier, le pushbutton Charger est alors cliquable, sans même que les champs nombre de lignes d'entête et nombre de colonnes soient renseignés.

  11. #11
    Invité
    Invité(e)
    Par défaut
    Re par ici

    Je ne comprends pas pourquoi le passage de l'un viderait l'autre... tu aurais le code correspondant ?

    Pour le deuxième problème, attention d'utiliser la propriété 'String' et non 'Value' qui ne sert pas pour les Edit.

  12. #12
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Pour le deuxième problème, attention d'utiliser la propriété 'String' et non 'Value' qui ne sert pas pour les Edit.
    En remplaçant la propriété 'Value' par la propriété 'String', renseigner les trois editbox ne permet pas de dégriser le pushbutton.

    Citation Envoyé par Winjerome Voir le message
    Je ne comprends pas pourquoi le passage de l'un viderait l'autre... tu aurais le code correspondant ?
    Voici le code correspondant à la fonction :

    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
    function dragFcn(obj,event,h)
    % Fonction à exécuter quand on déplace la souris
    % OBJ : identifiant de la fenetre courante
    % H : identifiant de la barre sélectionnée
     
    % On definit fig comme l objet parent %
    fig = ancestor(obj,'figure');
     
    % Recuperation des handles de fig %
    handles = guidata(fig);
     
    % Recuperation X et Y %
    X = getappdata(0,'X');  
    Y = getappdata(0,'Y'); 
     
    % Recuperation yA et yB %
    yA = getappdata(0,'yA');  
    yB = getappdata(0,'yB');  
     
    % Modification du pointeur de la souris %
    set(fig,'Pointer','Fleur');
     
    % Recuperation des coordonnees du pointeur de la souris %
    pt = get(gca,'CurrentPoint');
     
    % Modification de la position en x de la barre sélectionnee %
    set(h,'Xdata',[pt(1),pt(1)]);
     
    % Maj textbox avec position curseur A %
    xdataA = get(handles.hCurA,'XData');
     
    % Maj textbox avec position curseur B %
    xdataB = get(handles.hCurB,'XData');
     
    % Interpolation y au pointeur souris %
    y = interp1(X,Y,pt(1));
     
    % Affichage coordonnees %
    if h == handles.hCurA
        set(handles.hTextA,'Position',[xdataA(2) y],...
            'String',sprintf('(%0.3f, %0.3f)',xdataA(2),y)); 
     
        TextA = get(handles.hTextA,'String');
        [~,yA] = strread(TextA,'%s %s','delimiter',', ');
        yA = str2double(strrep(yA{1},')',''));
     
    elseif h == handles.hCurB
        set(handles.hTextB,'Position',[xdataB(2) y],...
            'String',sprintf('(%0.3f, %0.3f)',xdataB(2),y)); 
     
        TextB = get(handles.hTextB,'String');
        [~,yB] = strread(TextB,'%s %s','delimiter',', ');
        yB = str2double(strrep(yB{1},')','')); 
    end
     
    % Affichage delta X et delta Y %
    deltaX = abs(xdataB(2) - xdataA(2));
    set(handles.editdeltaX,'String',sprintf('%0.3f',deltaX));  
     
    if ~isempty(yA) && ~isempty(yB)
        deltaY = abs(yB - yA);
        set(handles.editdeltaY,'String',sprintf('%0.3f',deltaY));  
    end
     
    % Enregistrement deltaX et Y pour utilisation ulterieure %
    setappdata(0,'deltaX',deltaX);
    setappdata(0,'deltaY',deltaY);
     
    end
    Je te joins le script dans son intégralité ainsi qu'un fichier test en pièces attachées (5 lignes d'entête, 3 colonnes), ce sera peut être plus pratique pour identifier le problème :

  13. #13
    Invité
    Invité(e)
    Par défaut
    Tu oublies de re-stocker tes variables avec setappdata à la fin de la fonction. De ce fait, tu recharges encore toujours les mêmes valeurs vides.

    Pour le bouton charger, il te faudrait vérifier l'état des 3 Edit à chaque changement de l'un deux, et ne pas seulement le mettre à 'On', mais aussi à 'Off' selon les conditions.
    Ou peut-être plus simple : effectuer cette vérification au début de la fonction Charger, et afficher un message le cas échéant.
    Dernière modification par Invité ; 02/04/2014 à 18h49.

  14. #14
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Tu oublies de re-stocker tes variables avec setappdata à la fin de la fonction. De ce fait, tu recharges encore toujours les mêmes valeurs vides.
    Je n'y avais pas pensé. Merci beaucoup !

    Pour le reste, je viens de vérifier, renseigner les deux editbox Nombre de ligne d'entête et Nombre de colonnes ne met pas à jour automatiquement leurs propriétés 'String'. Elles restent vides quoique l'on inscrive dans ces deux editbox. La propriété 'String' de l'editbox pour le nom du fichier est quant à elle bien actualisée une fois le fichier sélectionné.

    J'ai trouvé un début de solution ici. S'il existe un moyen plus simple, je suis preneur.

  15. #15
    Invité
    Invité(e)
    Par défaut
    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
    editNbHdL= uicontrol(panelCharFich,... % inutile : tu utilises le tag
        'style','edit',...
        'units','normalized',...
        'position',[0.622 0.300 0.04 0.48],...
        'string','',...
        'tag','editNbHdL',...
        'Callback', @(~, ~) checkLoadButtonState(fig),... 
        'backgroundcolor',[1 1 1]);
    
    editNbCol= uicontrol(panelCharFich,... % idem
        'style','edit',...
        'units','normalized',...
        'position',[0.759 0.300 0.04 0.48],...
        'string','',...
        'tag','editNbCol',...
        'Callback', @(~, ~) checkLoadButtonState(fig),...
        'backgroundcolor',[1 1 1]);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function Select(obj,event)
     
        % ...
        checkLoadButtonState(fig)
    end
    Avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function checkLoadButtonState(fig)
     
        handles = guidata(fig);
     
        if    ~isempty(get(handles.NomFich,'String')) ...
           && ~isempty(get(handles.editNbHdL,'String')) ...
           && ~isempty(get(handles.editNbCol,'String'))
             set(handles.pushCharger,'Enable','on');
        else
             set(handles.pushCharger,'Enable','off');
        end    
    end

  16. #16
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Un grand merci Jerome !

    Une dernière question, pourquoi un telle syntaxe ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'Callback', @(~, ~) checkLoadButtonState(fig)

  17. #17
    Invité
    Invité(e)
    Par défaut
    Pourquoi pas
    On doit obligatoirement fournir une fonction prenant deux entrées : hObject et eventdata. Or moi je ne me sers d'aucun de ces deux paramètres passés automatiquement (~ donc) et veux passer le handle de l'objet Figure (fig que j'utilise avec guidata dans la fonction).
    Dernière modification par Invité ; 03/12/2014 à 09h06.

  18. #18
    Membre régulier
    Inscrit en
    Décembre 2012
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    Merci beaucoup pour l'explication

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

Discussions similaires

  1. Afficher un ArrayList sous forme d'une tableau HTML
    Par Peerofloo dans le forum Struts 1
    Réponses: 5
    Dernier message: 30/03/2007, 14h50
  2. Afficher une liste sous forme de tableau [SWING]
    Par Sylver--- dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 04/03/2007, 15h17
  3. asp - afficher un graphique sous forme de camembert
    Par Franck2mars dans le forum ASP
    Réponses: 5
    Dernier message: 22/01/2007, 08h26
  4. Réponses: 2
    Dernier message: 27/02/2006, 10h08
  5. [MySQL] Afficher image stockée sous forme binaire
    Par Luffy Duck dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 26/12/2005, 18h30

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