Précédent   Forum des professionnels en informatique > Environnements de développement > MATLAB > Interfaces Graphiques
Interfaces Graphiques Forum d'entraide sur les interfaces graphiques en MATLAB
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/02/2012, 16h50   #21
Modérateur
 
Avatar de Winjerome
 
Homme Jérôme
Inscription : septembre 2009
Messages : 3 598
Détails du profil
Informations personnelles :
Nom : Homme Jérôme
Âge : 24
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : septembre 2009
Messages : 3 598
Points : 6 824
Points : 6 824
Citation:
Envoyé par tachmou Voir le message
==> Ce n'est pas possible : quand on est dans la fonction myupdateFcn, on n'a pas accès à notre objet (this est inaccessible).
>> D'où l'intérêt d'utiliser myupdateFcn en tant que fonction imbriquée.
__________________
Débutant en MATLAB? Vous voulez faire une Interface Graphique? Les Tutoriels et la FAQ sont là pour vous aider
Une erreur? FAQ : Messages d'erreur et avertissements
"Ça ne marche pas" n'est pas une réponse acceptable Expliquez clairement votre problème (erreurs, résultats non attendus...).
Citation:
En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
Je suis régulièrement sur le chat DVP - Pas de question technique par MP, Merci
Winjerome est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2012, 09h29   #22
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

J'avais aussi essayé, ça ne fonctionnait pas (exactement le même comportement).

Je mets en résolu. Je posterai de nouvelles versions au fur et à mesure. Voici la première version, fonctionnelle avec l'aide disponible (help uiindexer) :

uiindexer.m
Code :
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
function this = uiindexer(varargin)
% UIINDEXER trace une serie de points et permets de recuperer l'index du
% point sur lequel on clique, en temps reel
%
%   Prend une serie de couples "propriete, valeur" en entree
%   A = uiindexer(prop1, val1, prop2, val2, ...)
%   Aucun ordre n'est necessaire pour la specification de ces couples.
%
% Proprietes disponibles :
%   
%   'figure'   : handle de la figure *
%   'axes'     : handle de l'axe (le parent de l'axe doit etre la figure) *
%   'data'     : les donnees traitees, si possible sur une seule ligne ou une
%                seule colonne
%   'callback' : handle de la fonction a executer lorsqu'on change de point
%                selectionne avec la souris sur le graphique
%   'texte'    : handle de la fonction a executer qui doit retourner le
%                texte a afficher. Exemple (si le uiindexer s'appelle A) :
%                function txt = aTexte()
%                    txt = {['Reel  : ', num2str(A.x())], ...
%                           ['Imag  : ', num2str(A.y())], ...
%                           ['Index : ', num2str(A.index())]};
%                end
%
%   * si aucune figure n'est specifiee, ou que l'axe n'est pas dans la
%     figure specifiee, alors une nouvelle figure est cree
%
% Accesseurs disponibles :
%
%   A.figure() : handle de la figure
%   A.axes()   : handle de l'axe
%   A.data()   : donnees affichees
%   A.index()  : index courant
%   A.x()      : abscisse du point courant
%   A.y()      : ordonnee du point courant
%
% Methodes disponibles :
%
%   A.callback(@aCallback) : change le callback
%   A.texte(@aTexte)       : change le texte a afficher dans la bulle
%
% Utilisation immediate dans le Command Window
% --------------------------------------------
%
% A = uiindexer
%
% % Cliquer sur un point de la figure, et afficher l'index courant avec :
%
% A.index()
%
% Exemple simple a enregistrer dans test.m et a executer
% ------------------------------------------------------
%
% function test
%     A = uiindexer('data', [-5-5*i -4+4*i -3-3*i -2+2*i -1-i 0 1+i 2-2*i 3+3*i 4-4*i 5+5*i], 'callback', @monCallback);
%     
%     A.texte(@aTexte)
%
%     function txt = aTexte
%         txt = {['Abscisse  : ', num2str(A.x())], ...
%                ['Ordonnee  : ', num2str(A.y())], ...
%                ['Index         : ', num2str(A.index())]};
%     end
% 
%     function monCallback
%         b = A.data();
%         disp( [  'A('  ,  num2str(A.index())  ,  ') = '  ,  num2str(b(A.index()))  ] );
%     end
% end

% MAJ 2012-02-09

    %% VARIABLES INTERNES
    data = [];              % donnees a afficher
    index = 0;              % index courant
    old_index = 0;          % ancien index (limite les maj)
    f = [];                 % figure handle
    a = [];                 % axe handle
    callback = [];          % callback handle
    texte = [];             % texte a afficher handle
    x = 0;                  % abscisse courante
    y = 0;                  % ordonnee courante
    pos = 0;                % position courante (x,y)
    txt = 0;                % texte a afficher
    
    %% ACCESSEURS ET METHODES
    this = struct(...
        'figure',           @getFigure, ...
        'axes',             @getAxes, ...
        'data',             @getData, ...
        'index',            @getIndex, ...
        'x',                @getX, ...
        'y',                @getY, ...
        'callback',         @setCallback, ...
        'texte',            @setTexte);
    
    %% CONSTRUCTEURS
    if mod(nargin, 2) == 1
        error('Mauvais format en entree : admet uniquement des couples (propriete, valeur)... tapez "help uiindexer" pour de plus amples informations.')
    else
        inputs = varargin;
        while length(inputs) >= 2
            prop = inputs{1};
            val  = inputs{2};
            inputs = inputs(3:end);
            switch lower(prop)
                case 'figure'
                    f = val;
                case 'axes'
                    a = val;
                case 'data'
                    data = val;
                case 'index'
                    disp('??? Warning ==> impossible to set "index" property')
                case 'callback'
                    callback = val;
                case 'texte'
                    texte = val;
                otherwise
                    error(['The property "' num2str(prop) '" is not supported.'])
            end
        end
        if isempty(data)
            data = [-2-2*i 2+2*i -1+i 1+i 1-i -1-i];
        end
        if isempty(index)
            index = 3;
        end
        if isempty(f)
            f = figure;
        end
        if isempty(a)
            a = axes('parent', f);
        elseif get(a, 'parent') ~= f
            a = axes('parent', f)
        end
        if isempty(callback)
            callback = 0;
        end
        
        % Configuration du curseur
        dcm_obj = datacursormode(f);
        set(dcm_obj, 'enable', 'on', ...
            'snaptodatavertex', 'on', ...
            'displaystyle', 'datatip', ...
            'UpdateFcn', @updateIndex);
        
        % Affichage
        plot(a, data, 'x');
    end
    
    %% ACCESSEURS
    
    function out = getFigure()
        out = f;
    end

    function out = getAxes()
        out = a;
    end
    
    function out = getData()
        out = data;
    end

    function out = getIndex()
        out = index;
    end

    function out = getX()
        out = x;
    end

    function out = getY()
        out = y;
    end

    %% METHODES

    function setCallback(in)
        callback = in;
    end

    function setTexte(in)
        texte = in;
    end
    
    %% CONFIGURATION DU CALLBACK

    function txt = updateIndex(empt, event_obj)
        index = get(event_obj, 'DataIndex');
        if old_index ~= index
            pos = get(event_obj, 'Position');
            x = pos(1);
            y = pos(2);
            old_index = index;
            callback();
        end
        if isempty(texte)
            txt = {['Reel  : ', num2str(pos(1))], ...
                ['Imag  : ', num2str(pos(2))], ...
                ['Index : ', num2str(index)]};
        else
            txt = texte();
        end
    end
end
Un fichier d'exemple d'implémentation dans un programme simple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function test
% Pour plus d'information :
%
% help uiindexer

% MAJ 2012-02-09

    A = uiindexer('data', [-5-5*i -4+4*i -3-3*i -2+2*i -1-i 0 1+i 2-2*i 3+3*i 4-4*i 5+5*i], 'callback', @monCallback);
    A.texte(@aTexte)
    
    function txt = aTexte
        txt = {['Abscisse  : ', num2str(A.x())], ...
               ['Ordonnee  : ', num2str(A.y())], ...
               ['Index         : ', num2str(A.index())]};
    end

    function monCallback
        b = A.data();
        disp( [  'A('  ,  num2str(A.index())  ,  ') = '  ,  num2str(b(A.index()))  ] );
    end
end
Si certaine personnes sont intéressées par ce code, et seraient intéressées d'avoir de nouvelles fonctionnalités, je les invite à les demander ici. En fonction de la difficulté, de l'intérêt que cela apporte pour mon équipe, et du temps que cela prend pour le coder, je le ferai peut-être et le proposerai donc dans une nouvelle version. Si d'autres personnes veulent proposer une nouvelle version, je les invite à le faire également.

Futures fonctionnalités envisagées :
- configuration du datacursormode
- le faire fonctionner sur des plot différents, avec possibilité de choisir le type de plot sur lequel on veut dessiner (logarithmique par exemple, ou bien un bode "personnalisé"... j'envisage d'implanter un nouveau plot type "bode" mais qui laisse l'accès à la courbe de gain, et permet d'afficher / de mettre en valeur des caractéristiques remarquables comme la pulsation propre, les marges etc... - tout ceci via des options)

Cordialement,

ps: j'ai un petit bug à la con... lorsque je fais "help uiindexer", la première ligne de l'aide de "uiindexer.m" s'affiche puis la première ligne de l'aide de "test.m" s'affiche puis toute l'aide de "uiindexer.m" s'affiche enfin (y compris la première ligne qu'on voit donc affichée deux fois au final...). Un peu chelou cette histoire : vous avez le même problème ou pas ?

[EDIT] : en réalité, j'avais mis mes fichiers dans un répertoire portant le même nom que ma fonction... et lorsqu'on tape "help quelquechose", matlab cherche d'abord un dossier portant le nom "quelquechose"... s'il en trouve un, il cite les premières lignes d'aide de chaque fichier contenu dans "/quelquechose/". Ensuite, quoi qu'il en soit, il cite l'aide du fichier "quelquechose.m" s'il en trouve un. D'où mon "bug" qui n'en est pas un en fait, c'est juste que l'aide matlab ne le dit pas. D'ailleurs c'est bon à savoir, si on mets plusieurs fichiers "*.m" dans un répertoire, et qu'on tape help "nomdurépertoire", on obtient la première ligne d'aide de chaque fichier. D'ailleurs, c'est cette ligne qui est affichée dans la colonne "Description" en face de chaque fichier dans l'explorateur "Current Directory". Donc : problème entièrement résolu

Enjoy!
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2012, 13h57   #23
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Voici une nouvelle version (légères optimisations à droite à gauche).

Je ne la modifierai pas avant un bout de temps je pense. Entièrement libre. J'invite qui le veut bien de l'améliorer et/ou d'y apporter de nouvelles fonctionnalités et de poster sa version mise à jour ici.

uiindexer.m
Code :
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
function this = uiindexer(varargin)
% UIINDEXER trace une serie de points et permets de recuperer l'index du
% point sur lequel on clique, en temps reel
%
%   Prend une serie de couples "propriete, valeur" en entree
%  .----------------------------------------------.
%  | A = uiindexer(prop1, val1, prop2, val2, ...) |
%  '----------------------------------------------'
%   Aucun ordre n'est necessaire pour la specification de ces couples.
%
% Proprietes (prop1, prop2, ...) disponibles avec valeurs a associer :
%   
%   'figure'   : handle de la figure *
%   'axes'     : handle de l'axe (le parent de l'axe doit etre la figure) *
%   'data'     : les donnees traitees, si possible sur une seule ligne ou une
%                seule colonne
%   'callback' : handle de la fonction a executer lorsqu'on change de point
%                selectionne avec la souris sur le graphique
%   'texte'    : handle de la fonction a executer qui doit retourner le
%                texte a afficher. Exemple (si le uiindexer s'appelle A) :
%                function txt = aTexte()
%                    txt = {['Reel  : ', num2str(A.x())], ...
%                           ['Imag  : ', num2str(A.y())], ...
%                           ['Index : ', num2str(A.index())]};
%                end
%
%   * si aucune figure n'est specifiee, ou que l'axe n'est pas dans la
%     figure specifiee, alors une nouvelle figure est cree
%
% Accesseurs disponibles :
%
%   A.figure() : handle de la figure
%   A.axes()   : handle de l'axe
%   A.data()   : donnees affichees
%   A.index()  : index courant
%   A.x()      : abscisse du point courant
%   A.y()      : ordonnee du point courant
%
% Methodes disponibles :
%
%   A.callback(@aCallback) : change la propriete 'callback'
%   A.texte(@aTexte)       : change la propriete 'texte'
%
% Utilisation immediate dans le Command Window
% --------------------------------------------
%
% A = uiindexer
%
% % Cliquer sur un point de la figure, et afficher l'index courant avec :
%
% A.index()
%
% Exemple simple a enregistrer dans test.m et a executer
% ------------------------------------------------------
%
% function test
%     A = uiindexer('data', [-5-5*i -4+4*i -3-3*i -2+2*i -1-i 0 1+i 2-2*i 3+3*i 4-4*i 5+5*i], 'callback', @monCallback);
%     
%     A.texte(@aTexte)
%
%     function txt = aTexte
%         txt = {['Abscisse  : ', num2str(A.x())], ...
%                ['Ordonnee  : ', num2str(A.y())], ...
%                ['Index         : ', num2str(A.index())]};
%     end
% 
%     function monCallback
%         b = A.data();
%         disp( [  'A('  ,  num2str(A.index())  ,  ') = '  ,  num2str(b(A.index()))  ] );
%     end
% end

% MAJ 2012-02-16

    %% VARIABLES PRIVEES
    data = [];              % donnees a afficher
    index = 0;              % index courant
    old_index = 0;          % ancien index (limite les maj)
    f = [];                 % figure handle
    a = [];                 % axe handle
    callback = [];          % callback handle
    texte = [];             % texte a afficher handle
    x = 0;                  % abscisse courante
    y = 0;                  % ordonnee courante
    pos = 0;                % position courante (x,y)
    txt = 0;                % texte a afficher
    
    %% LISTE ACCESSEURS ET METHODES
    this = struct(...
        'figure',           @getFigure, ...
        'axes',             @getAxes, ...
        'data',             @getData, ...
        'index',            @getIndex, ...
        'x',                @getX, ...
        'y',                @getY, ...
        'callback',         @setCallback, ...
        'texte',            @setTexte);
    
    %% CONSTRUCTEUR
    if mod(nargin, 2) == 1
        error('Mauvais format en entree : admet uniquement des couples (propriete, valeur)... tapez "help uiindexer" pour de plus amples informations.')
    else
        inputs = varargin;
        while length(inputs) >= 2
            prop = inputs{1};
            val  = inputs{2};
            inputs = inputs(3:end);
            switch lower(prop)
                case 'figure'
                    f = val;
                case 'axes'
                    a = val;
                case 'data'
                    data = val;
                case 'index'
                    disp('??? Warning ==> impossible to set "index" property')
                case 'callback'
                    callback = val;
                case 'texte'
                    texte = val;
                otherwise
                    error(['The property "' num2str(prop) '" is not supported.'])
            end
        end
        if isempty(data)
            data = [-2-2*i 2+2*i -1+i 1+i 1-i -1-i];
        end
        if isempty(index)
            index = 3;
        end
        if isempty(f)
            f = figure;
        end
        if isempty(a)
            a = axes('parent', f);
            plot(a, data, 'x');
        elseif get(a, 'parent') ~= f
            a = axes('parent', f)
            plot(a, data, 'x');
        end
        if isempty(callback)
            callback = 0;
        end
        
        % Configuration du curseur
        dcm_obj = datacursormode(f);
        set(dcm_obj, 'enable', 'on', ...
            'snaptodatavertex', 'on', ...
            'displaystyle', 'datatip', ...
            'UpdateFcn', @updateIndex);
        
    end
    
    %% ACCESSEURS
    
    function out = getFigure()
        out = f;
    end

    function out = getAxes()
        out = a;
    end
    
    function out = getData()
        out = data;
    end

    function out = getIndex()
        out = index;
    end

    function out = getX()
        out = x;
    end

    function out = getY()
        out = y;
    end

    %% METHODES

    function setCallback(in)
        callback = in;
    end

    function setTexte(in)
        texte = in;
    end
    
    %% CONFIGURATION DU CALLBACK

    function txt = updateIndex(empt, event_obj)
        index = get(event_obj, 'DataIndex');
        if old_index ~= index
            pos = get(event_obj, 'Position');
            x = pos(1);
            y = pos(2);
            old_index = index;
            callback();
        end
        if isempty(texte)
            txt = {['Reel  : ', num2str(pos(1))], ...
                ['Imag  : ', num2str(pos(2))], ...
                ['Index : ', num2str(index)]};
        else
            txt = texte();
        end
    end
end

test.m
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
% Pour plus d'information : help uiindexer
function test

% MAJ 2012-02-16
    f = figure;
    ax = axes('parent', f);

    A = uiindexer('figure', f, 'axes', ax, 'data', [-5-5*i -4+4*i -3-3*i -2+2*i -1-i 0 1+i 2-2*i 3+3*i 4-4*i 5+5*i], 'callback', @monCallback);
    A.texte(@aTexte)
    
    plot(ax, [-5-5*i -4+4*i -3-3*i -2+2*i -1-i 0 1+i 2-2*i 3+3*i 4-4*i 5+5*i], 'x');
    
    function txt = aTexte
        txt = {['Abscisse  : ', num2str(A.x())], ...
               ['Ordonnee  : ', num2str(A.y())], ...
               ['Index         : ', num2str(A.index())]};
    end

    function monCallback
        b = A.data();
        disp( [  'A('  ,  num2str(A.index())  ,  ') = '  ,  num2str(b(A.index()))  ] );
    end
end
Cordialement,
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h19.


 
 
 
 
Partenaires

Hébergement Web