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 01/02/2012, 10h37   #1
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Par défaut [datacursormode] Bloquer la vue d'un plot3, puis récupérer les coordonnées dans le programme

Bonjour,

Cette discussion fait suite à celle-ci à titre d'information.

Je souhaite afficher une série de points 3D dans un graphique 3D, mais bloquer la vue selon une direction, de telle sorte que l'utilisateur ne puisse pas tourner le graphique avec les options disponibles. Cela est-il faisable ?

Par exemple, le code suivant affiche les pôles d'un système dans un graphique 3D (sur 'x' la partie réelle, sur 'y' la partie imaginaire et sur 'z' l'indice) et affiche la vue dans une certaine direction :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
sys=tf([1], [1 2 3 4 5]); % ma fonction de transfert
mesPoles=pole(sys);       % mes poles
[m,n]=size(mesPoles);     % le nombre de poles dans m
x=real(mesPoles);         % partie réelle des poles
y=imag(mesPoles);         % partie imaginaire des poles
z(m)=0;                   % indice de repérage des poles
for k=1:1:m
    z(k) = k;
end

plot3(x,y,z,'x');         % mon graphique avec des croix pour chaque point
view([0 0 1])             % vue de dessus
Je voudrais donc déjà, en premier lieu, bloquer la vue. (tourner la vue est l'une des options disponibles au dessus du graphique).

Mon objectif final est de récupérer les données (d'un point de vue programmation) qui ont permis de tracer le pôle sur lequel l'utilisateur va cliquer : pas seulement les valeurs 'x' & 'y', mais également l'indice 'z' qui me permet de les repérer dans "mesPoles". Je crois que j'ai déjà une piste avec "datacursormode"... j'ai donc déjà ma petite idée pour ce problème, mais pas pour le premier qui consiste à bloquer la vue. (A moins que quelqu'un sache directement comment récupérer l'indice des points tracés dans une vue 2D)

Je vous remercie par avance pour toute aide.

Cordialement,

[EDIT] Après recherches un peu plus approfondies, j'ai trouvé comment récupérer l'indice du point sélectionné. Je l'ai appliqué sur un graphique 2D et ça marche bien (du moins ça l'affiche dans la console en temps réel). Exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function testPoles
sys = tf([1], [1 2 3 4 5];
mesPoles = poles(sys);

f=figure(1);
plot(mesPoles, 'x')

dcm_obj=datacursormode(f);
set(dcm_obj, 'enable', 'on', ...             % activation du curseur
    'snaptodatavertex', 'on', ...            % le curseur s'aligne sur les points donnés uniqumeent
    'displaystyle', 'datatip', ...           % mode d'affichage (window ou datatip)
    'UpdateFcn', @myupdatefcn);

    function [txt, pos, indice] = my updatefcn(empt, event_obj)
        pos = get(event_obj, 'Position')     % récupère et affiche les coordonnées x et y du point
        indice = get(event_obj, 'DataIndex') % récupère et affiche l'indice du point
        txt = {['Re: ', num2str(pos(1))], ['Im: ', num2str(pos(2))], ['Index: ', num2str(indice)]};
    end
end
Maintenant, il faut encore que je sache comment je peux traiter ces données en temps réel dans mon programme pour faire ce que je veux, mais ça, c'est un autre problème.

Il n'empêche que j'aimerai savoir s'il est possible de bloquer la vue 3D.
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 14h37   #2
Dut
Rédacteur/Modérateur
 
Avatar de Dut
 
Inscription : novembre 2006
Messages : 12 919
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : novembre 2006
Messages : 12 919
Points : 15 909
Points : 15 909
Citation:
Envoyé par tachmou Voir le message
Je voudrais donc déjà, en premier lieu, bloquer la vue. (tourner la vue est l'une des options disponibles au dessus du graphique).
Tu peux rendre le bouton concerné invisible :
Code :
1
2
3
h = findall(0,'type','uitoggletool','tooltipstring','Rotate 3D');
set(h,'visible','off');
C'est bien entendu réversible
__________________
Mes contributions MATLAB (R2009a - Windows & Linux)

• 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)
• Des larmes coulèrent doucement des yeux fermés du vieil homme. Moi je pleurais comme un enfant, que d'ailleurs pour lui je ne cesserais d'être ma vie durant (Amkoullel)

• Lâché de Mogwai sur St Malo... aie aie aie... ouille ouille ouille
Dut est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/02/2012, 14h52   #3
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Merci encore pour ta réponse ! J'espère que cette réponse sera utile également à d'autres personnes et pas seulement à moi.

Bon, maintenant, il faudrait qu'en fonction de la dernière valeur enregistrée dans "indice", je puisse mettre à jour tout le reste du programme qui dépend de mon fameux "indice"...

Je suis formaté "Qt", donc si tu connais, en gros, j'aimerai créer une sorte de "signal" qui se déclenche dès que la valeur de mon "indice" change et qui puisse être lié à un "slot" dans lequel je pourrais faire toutes les modifications que je veux...
...mieux encore : j'aimerai que cette variable soit la sortie de ma fonction "dessinerEtRecupererIndice" (qui s'occupe donc de dessiner dans un "axe" les données d'entrée et de donner la possibilité à l'utilisateur de venir cliquer sur les points pour récupérer mon "indice" avant de le donner en sortie...) et que je puisse traiter dans mon programme principal le changement de valeur de cette sortie comme bon me semble.

Voici un code de base :

Programme principal
Code :
1
2
3
4
5
6
7
sys = tf([1], [1 2 3 4 5]);
mesPoles = pole(sys);
a = axes;
[indice] = dessinerEtRecupererIndice(a, mesPoles);

%% Code à rajouter pour traiter le changement de valeur d'indice
%%
Fonction récupérer indice
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function [indice] = dessinerEtRecupererIndice(a, mesPoles) %% <<= Rq. : j'ai mis indice en sortie
    plot(mesPoles, 'x') %% <<= ici j'aimerai aussi spécifier que je veux dessiner dans mon axe "a"... je ne sais pas comment faire non plus - certes ça le fait comme il faut si axe est le dernier élément créé... mais c'est magique ça aussi... et si jamais j'ai créé un autre axe ou figure entre temps ? et que je veux quand même l'afficher dans l'ancien axe ? 
    dcm_obj = datacursormode(a)
    set(dcm_obj, 'enable', 'on', ... 
        'snaptodatavertex', 'on', ... 
        'displaystyle', 'datatip', ...
        'UpdateFcn', @myupdatefcn);

    function [txt, indice] = myupdatefcn(empt, event_obj)  << j'ai mis "indice" en sortie
        pos = get(event_obj, 'Position');
        indice = get(event_obj, 'DataIndex');
        txt = {['Re: ', num2str(pos(1))], ['Im: ', num2str(pos(2))], ['Index: ', num2str(indice)]};
    end
end
(Codes non fonctionnels bien sûr)

Je m'y prends très certainement très mal : n'hésitez pas à me l'indiquer ! J'aimerai juste un petit coup de pouce, je pense qu'il ne me manque pas grand chose pour que je puisse (enfin!) commencer à développer les outils dont j'ai besoin pour ma thèse...

Cordialement,

ps : Dis moi, j'en ai marre de poser des questions idiotes... il n'y aurait pas une doc un peu mieux foutu que l'officielle ? Comme tu as dû le remarquer, je cherche à faire des choses un minimum évoluées, et les infos intéressantes sont extrêmement éparpillées je trouve... en clair : je galère trop pour faire ce que j'ai envie de faire. Tu n'aurais pas un conseil "magique" à me donner à tout hasard ? D'ailleurs, comment tu as fait pour répondre à ma question ? Comment tu le sais ça, qu'il fallait chercher la propriété "tooltipstring" et que sa valeur est "Rotate 3D" ? C'est magique ça quand même...

ps2 : délire perso parce que je craque... j'aimerai bien faire ctrl+c de ton cerveau partie matlab et ctrl+v dans le mien partie matlab... ok je sors
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 16h02   #4
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
Bonjour,

Code :
function [txt, indice] = myupdatefcn(empt, event_obj)  << j'ai mis "indice" en sortie
Étant contenu dans le fonctionnement interne du DATACURSORMODE, tu ne pourras pas récupérer tes indices de cette façon.
Ce qui se rapproche le plus de ce que tu demandes sur les signaux/slots serait ceci qui est plus tourné Java. Mais il te serait plus simple d'utiliser le principe des fonctions imbriquées et de mettre ton traitement sur les indices directement dans la fonction myupdatefcn.

Pour ce qui est du PLOT:
Pour ce qui est du 'TooltipString', il faut juste savoir que les boutons présents sur la Toolbar des Figures sont des objets Uitoggletool, et que lors du survol de la souris, c'est le contenu de leur propriété 'TooltipString' qui est affiché. À partir de là, on recherche le handle de l'objet à partir de ces caractéristiques connues avec la fonction FINDALL.
__________________
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 10
Vieux 01/02/2012, 16h28   #5
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Merci pour tes deux dernières réponses (le plot et le TooltipString, d'ailleurs j'ai envie de dire : "Tricheur!" mais merci pour le tuyau )

Par contre, la première réponse ne me fait pas plaisir pour trois raisons :
- Le lien que tu me files concernant les classes nécessite les dernières versions de Matlab... je ne l'avais pas spécifié ici, mais en fait je me trimballe avec la version 7R14 de 2005. J'ai d'ailleurs trouvé un autre moyen de créer des classes en utilisant justement les fonctions imbriquées.
- Traiter les données dans la fonction myupdatefcn est juste "pas envisageable" : je compte utiliser ce type de fonctionnalité des dizaines voire des centaines de fois selon l'application/les système que je vais concevoir.
- Je ne peux pas mettre mon "indice" en sortie... bon ok soit, mais il doit y avoir peut être moyen de faire une magouille avec les entrées non ? Et de jouer avec les "update" utilisé dans les gui ? Je m'explique...

L'idée que j'ai mais que je n'arrive pas à concrétiser proprement, serait de créer (par exemple) un slider (ou autre...) qui ne serait pas visible sur la figure principale, et qui contient la valeur de mon indice. J'envoie le handle de ce slider en entrée de ma fonction "dessinerEtRecupererIndice", ainsi qu'en entrée de la fonction "myupdatefcn". Je mets donc à jour la valeur contenue dans mon slider... qui, en changeant, va appeler son "Callback" ! Et là, paf! ça fait des chokapik! (puisque dans le callback du slider qui m'intéresse je fais mon joyeux bordel... qui se trouvera donc comme je le voulais dans ma fonction principale !)

Les applications sont multiples et j'envisage même de gérer différents types de plots etc... (j'en ai réellement besoin pour ma thèse si je veux répondre efficacement à une partie de mon sujet... ce n'est donc pas du superflu que je demande là)

Galère galère...

Merci à tous ceux qui ont eu le courage de me lire ! Ca paraît tordu, mais ça serait tellement utile et permettrait de faire tellement de choses !
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 17h09   #6
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
Merci pour tes deux dernières réponses (le plot et le TooltipString, d'ailleurs j'ai envie de dire : "Tricheur!" mais merci pour le tuyau )
Bon d'accord l'expérience ça aide, mais l'histoire du plot c'est contenu dans la doc:
Citation:
Envoyé par doc plot
plot(axes_handle,...) plots using axes with the handle axes_handle instead of the current axes (gca).
Le reste dans l'excellent tutoriel de Dut.

Ensuite comme je te l'ai dit, le plus simple est d'utiliser les fonctions imbriquées, cependant je ne pensais pas à aux classes de l'autre discussion, mais simplement au passage de variable.
Je ne vois pas en quoi
Citation:
Envoyé par tachmou Voir le message
Traiter les données dans la fonction myupdatefcn est juste "pas envisageable"
Tu veux bien appeler ton Callback à chaque changement, non? Ou ai-je mal compris?
__________________
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 02/02/2012, 09h43   #7
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Oui, tu as bien compris ce point, mais... !

En fait, j'ai l'intention d'utiliser cette fonction pour afficher des dizaines de graphiques différents, avec des données d'entrées différentes à chaque fois (c'est là que je trouve matlab utile d'ailleurs)... et donc, ce que je veux mettre dans mes callback... sera différent selon l'utilisation ! D'où ma question...

Et puis, pour faire simple, l'indice que je vais récupérer avec ma souris, me permettra, à la fin, d'accéder à environ une centaine de variables (au très très bas mot...) - et ce - pour chacun des dizaines de graphiques différents ou je veux cette fonctionnalité : l'interprétation dépendra donc de l'étude que je suis en train de faire, et donc non pas du pauvre graphique que je viens d'afficher. Après tu me diras : tu es obligé de passer par des graphiques ?

Non, mais ça aide à la compréhension, et quand tu étudies un système MIMO (linéarisé pour l'étude N°0002134, ce qui est déjà "censé" simplifier le travail), les pôles du système entier sont affichés sur le même graphique... si je veux savoir à quelle entrée et à quelle sortie ils sont liés, avec la fonction "bodeplot" je suis mal barré

[En gros, pour faire schématique, imagine que je veuille faire un gui assez conséquent (je sais, matlab n'est pas prévu pour ça, il n'est prévu que pour faire des applications concrètes rapides, mais ça c'est un autre débat)... ce gui doit pouvoir proposer des outils de toutes sortes... pour structurer le tout et me simplifier la vie, je vais utiliser la POO de l'autre discussion (déjà appliqué en partie comme je l'ai dit, et c'est génial - merci encore d'ailleurs) et afficher des graphiques : seulement, j'ai environ une dizaine de graphiques différents à afficher, et je veux que chacun d'entre eux ai cette fonctionnalité qui me semble quand même assez basique : je suis fortement surpris que matlab ne propose pas dans sa magnifique doc une solution toute faite pour ça... comme ce n'est pas le cas, je m'attèle à cette tâche, j'en fait une classe ou une fonction qu'il faudra utiliser d'une certaine manière, et je l'utiliserai pour chacun des graphiques que j'aurai besoin d'afficher (je n'ai pas que des pôles à afficher, j'ai des courbes temporelles, des bodes "faits à la main" - pareil, j'ai fait mon propre bode et j'y ai rajouté des fonctionnalités de "base" que matlab ne propose pas sur ses bodes - et d'autres graphiques issus de la normes, et peut être encore d'autres graphiques dont je n'ai même pas idée aujourd'hui... donc je voudrai m'éviter de me compliquer la tâche à devoir à chaque fois recoder la même chose, d'autant que vu la taille du programme que je dois faire, je me vois mal tout mettre dans le même fichier pour travailler sur le même workspace...]

Merci pour ton liens, je l'avais déjà épluché et ça m'avait bien aidé d'ailleurs, je les ai même imprimés en partie (en les résumant sur 3 pages) et affichés sur le mur juste en face de moi, je ne peux pas les louper ^^.

Cordialement,

ps: et pour répondre à une question qu'on m'a déjà posé : pourquoi je ne programme pas en C++ avec Qt directement ? Pour trois raisons : 1) j'ai envie de maîtriser matlab 2) c'est le langage utilisé par mes encadrants 3) matlab propose pleins d'outils qui m'intéressent vraiment et permet de travailler "en live" si on veut faire des tests, et je n'ai pas envie de refaire une grosse partie de ce qui est déjà très bien fait sur matlab (rapidité des calculs en plus...)

ps2: la tâche paraît grosse... elle ne l'est pas tant que ça, il "suffit" de s'atteler à la tâche méthodiquement... et j'ai trois ans pour réaliser ma thèse, et on m'accorde quelques mois pour développer mes outils d'étude. Donc c'est faisable. Et puis si on ne se donne pas de challenge, c'est pas marrant !

[EDIT] : Quelqu'un d'autre a fait quelque chose de similaire et passe par un "handle global"... moche, mais si c'est la seule solution, je l'utiliserai. Je vais essayer de coder ça. (par contre il a eu des bugs, je vais voir tout ça)

[EDIT 2] : Aha! je pense que je tiens le bon bout avec evalin :
Citation:
evalin(ws, expression) executes expression, a string containing any valid MATLAB expression, in the context of the workspace ws. ws can have a value of 'base' or 'caller' to denote the MATLAB base workspace or the workspace of the caller function.
Niark niak...
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 15h17   #8
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
Je ne vois toujours pas en quoi cela est un problème
Je te propose un exemple simple, qui je l'espère t'aidera:
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
function exemple

figs(1) = figure('Units','Normalized',...
    'Position',[0.5 0.5 0.4 0.4]);
figs(2) = figure('Units','Normalized',...
    'Position',[0.5 0   0.4 0.4]);
figs(3) = figure('Units','Normalized',...
    'Position',[0   0   0.4 0.4]);
figs(4) = figure('Units','Normalized',...
    'Position',[0   0.5 0.4 0.4]);

axs(1) = axes('Parent',figs(1),...
    'NextPLot','replaceChildren',...
    'XLim',[0 10],...
    'YLim',[0 10]); hps(1) = plot(axs(1),NaN,NaN);
axs(2) = axes('Parent',figs(2),...
    'NextPLot','replaceChildren',...
    'XLim',[0 10],...
    'YLim',[0 10]); hps(2) = plot(axs(2),NaN,NaN);
axs(3) = axes('Parent',figs(3),...
    'NextPLot','replaceChildren',...
    'XLim',[0 10],...
    'YLim',[0 10]); hps(3) = plot(axs(3),NaN,NaN);
axs(4) = axes('Parent',figs(4),...
    'NextPLot','replaceChildren',...
    'XLim',[0 10],...
    'YLim',[0 10]); 

donnees = 1:10;
dessinerEtRecupererIndice(axs(4), donnees)
indice = [];
figure(figs(4))

    function dessinerEtRecupererIndice(a, mesPoles) %% <<= Rq. : j'ai mis indice en sortie
        plot(a,mesPoles, 'x') %% <<= ici j'aimerai aussi spécifier que je veux dessiner dans mon axe "a"... je ne sais pas comment faire non plus - certes ça le fait comme il faut si axe est le dernier élément créé... mais c'est magique ça aussi... et si jamais j'ai créé un autre axe ou figure entre temps ? et que je veux quand même l'afficher dans l'ancien axe ?
        dcm_obj = datacursormode(get(a,'Parent'));
        set(dcm_obj, ...
            'enable', 'on', ...
            'snaptodatavertex', 'on', ...
            'displaystyle', 'datatip', ...
            'UpdateFcn', @myupdatefcn);
    end
    function [txt] = myupdatefcn(empt, event_obj)
        pos = get(event_obj, 'Position');
        indice = get(event_obj, 'DataIndex');
        txt = {['Re: ', num2str(pos(1))], ['Im: ', num2str(pos(2))], ['Index: ', num2str(indice)]};
        MajTraces
    end
    function MajTraces
        set(hps(1),'XData',[indice indice], 'YData',ylim)
        set(hps(2),'XData',xlim, 'YData',[indice indice])
        set(hps(3),'XData',[0 indice], 'YData', [0 indice])
    end
end
__________________
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 02/02/2012, 16h15   #9
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Je te remercie beaucoup pour ton exemple, ça m'a éclairé sur certains autres points au passage, il est intéressant (sans ironie), mais...

Imagine que je veuille, pour mon application 1, faire "MajTraces1", puis pour mon application tartenpion, faire "MajTracesTartenpion", etc... je suis obligé de recoder tout ce que tu as fait à chaque fois et faire les traitements nécessaires dans toutes ces sous fonctions... c'est lourd et long (pas pour une petite application, mais pour un gros bordel si)

Moi j'imaginais plutôt coder une sorte de "boîte noire" que tu viendrais piocher parmis toutes les autres "boîtes noires" qui prend
En entrée :
- le handle de ton graphique (et peut-être d'autres options)
En "sortie" :
- l'index qui déclenche un callback à l'extérieur de sa propre fonction

Lorsque l'index change, ça déclenche un callback d'un certain type dans le programme de l'utilisateur, et lorsqu'il est déclenché, l'utilisateur fait ce qu'il veut dans son propre callback.

Je te rappelle que je suis thésard, et qui dit thésard dit gros gros gros fainéant : tout ce qui peut me simplifier la vie est bon à prendre (ou à développer dans mon cas).

Mais j'y suis presque, je posterai ma "boîte noire" en question.

Cordialement,

ps : ah et sinon j'ai trouvé un slider un peu mieux foutu que l'officiel sur matlab central... (concerne l'autre discussion) il n'est pas temps réel mais bon, c'est le genre de "boîte noire" que je comptais développer aussi. C'est déjà fait : tant mieux !
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 18h53   #10
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
N'ayant pas une vue globale sur ce que tu veux faire, il est difficile de bien t'orienter... Je ne fais qu'en fonction de ce que tu me dis (et ce que je comprends).
Après tu peux très bien te servir du principe de l'autre discussion et y rajouter les éléments de celle-ci.
__________________
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 03/02/2012, 16h37   #11
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bonjour,

Je me rends bien compte que je touche du doigt un point particulier. Avec le code suivant, tu devrais comprendre. L'intérêt, c'est qu'au final, grâce à ce "truc" que j'essaye de coder, eh bien l'utilisateur pourra l'utiliser en faisant par exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function gui_numero_xxx
    % Création des variables
    sys = tf([1], [1 2 3 4 5]);
    mesPoles = poles(sys);

    % Mise en place du graphique
    f = figure(1)
    a = axes('parent', f);
    i = uicontrol('Style', 'indexFromClick', ...
        'DataIn', mesPoles, 'parent', a, 'Value', 0, ...
        'Callback', @indexFromClick_Callback); % cf EXPLICATION après le cadre

    function indexFromClick_Callback(src, evt)
        % Mise à jour de mon programme dès que le 'Value' de l'index 'i' change 
    end    
    
end
EXPLICATION
Mon 'uicontrol' sera de type 'indexFromClick' (que je suis donc en train de créer, j'y arrive petit à petit, il faut que je règle quelques détails). Il a besoin des données à afficher 'DataIn' (ici mesPoles), du handle de l'axe où je veux les afficher (ici a), la valeur 'Value' par défaut (ici 0), et le nom du 'Callback' qui s’exécutera dès que la valeur de 'Value' changera (ici ma 'Value' sera la valeur de mon index...)

Pour cela, je suis en train d'apprendre le fonctionnement des timer (je viens donc vérifier régulièrement la valeur de mon index : dès qu'elle change, je déclenche la fonction "Callback"). Et pour pouvoir implémenter cela à la sauce (merdique soit dit en passant - oui je sais, je me mets toute la communauté matlab à dos) matlab, et bien j'ai besoin d'apprendre à faire des fonctions qui puissent s'utiliser avec des "set" et des "get".

Bon, ce ne sera peut-être pas un uicontrol, ce sera peut-être un autre truc au même niveau que "root" qui possèdera mon nom, mais ça c'est du détail .

Cordialement,

ps: vu à quel point je m'em***** pour faire cette fichu fonctionnalité, ce sera certainement la seule que je ferai, j'ai autre chose à faire après

ps2: si quelqu'un se sent de faire ce boulot à ma place gratuitement, j'accepte... (utopie, utopie, quand tu nous tiens !)
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2012, 18h02   #12
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
Alors une solution déjà mentionnée:
Citation:
Envoyé par Winjerome Voir le message
Ce qui se rapproche le plus de ce que tu demandes sur les signaux/slots serait ceci qui est plus tourné Java.
Mais comme tu m'as dit:
Citation:
Envoyé par tachmou Voir le message
- Le lien que tu me files concernant les classes nécessite les dernières versions de Matlab... je ne l'avais pas spécifié ici, mais en fait je me trimballe avec la version 7R14 de 2005.
Alors
Citation:
Envoyé par Winjerome Voir le message
Après tu peux très bien te servir du principe de l'autre discussion et y rajouter les éléments de celle-ci.
Il n'y a pas grand chose à changer sur ce qui a déjà été fait. Juste la gestion des entrées/sortie de ta "classe"
Allez au boulot
__________________
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 06/02/2012, 17h50   #13
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'ai une première version simplifiée fonctionnelle, mais pas comme je le souhaite car :
- j'utilise une variable globale alors que je voudrais pouvoir utiliser "get(a, 'index')" dans ma fonction "aCallback" (ce que je n'arrive pas à faire marcher)
- les "set" ne fonctionnent pas comme prévu
(je crois savoir d'où proviennent mes erreurs : j'ai utilisé des "nested functions" au lieu des functions classiques de matlab)

Je la poste quand même... Arborescence générale :
main/@uiindexer/uiindexer.m
main/@uiindexer/set.m
main/@uiindexer/get.m
main/main.m

main/@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
% uiindexer

function this = uiindexer(varargin)
    %% Definition de la structure de mon objet
    this = struct(...
        'data',                 [0],        ...
        'index',                0,          ...
        'callback',             0);
    global new_index;
    new_index = 0;
    old_index = 0;
    
    %% Constructeurs
    if nargin == 0 % par defaut
    end
    if nargin == 1 % de copie
        if (isa(varargin{1}, 'uiindexer'))
            this = varargin{1};
        else
            error('Wrong argument type')
        end
    else % quelconque
        property_argin = varargin(1:end);
        while (length(property_argin) >= 1)
            property = property_argin{1};
            value    = property_argin{2};
            property_argin = property_argin(3:end);
            switch lower(property)
                case 'datain'
                    this.data = value
                case 'callback'
                    this.callback = value;
                otherwise
                    msg = sprintf('Propriete inconnue : "%s"', property);
                    error(msg);
            end
        end
    end
    
    this.figure = figure;
    this.axe = axes('parent', this.figure);
    plot(this.axe, this.data, 'x');
    
    
    % Curseur    
    dcm_obj = datacursormode(this.figure);
    set(dcm_obj, 'enable', 'on', ...
        'snaptodatavertex', 'on', ...
        'displaystyle', 'datatip', ...
        'UpdateFcn', @myupdatefcn);
    function [txt, truc] = myupdatefcn(empt, event_obj)
        pos = get(event_obj, 'Position');
        new_index = get(event_obj,'DataIndex');
        txt = {['Reel : ', num2str(pos(1))], ...
            ['Imag : ', num2str(pos(2))], ...
            ['Index:', num2str(new_index)]};
    end

    % Demarrage
    t = timer;
    set(t, 'executionMode', 'fixedRate');
    set(t, 'timerFcn', @createCallback);
    set(t, 'Period', 0.01);
    start(t);
    function createCallback(obj, evt)
        if old_index ~= new_index
            old_index = new_index;
            this = set(this, 'index', new_index);
            this.callback();
        end
    end
    
    %% Sortie en tant que "class" matlab
    this = class(this, 'uiindexer');
end
main/@uiindexer/set.m
Code :
1
2
3
4
5
6
7
8
9
10
11
function a = set(a, propName, propValue)
    propName = lower(propName)
    switch propName
        case 'datain'
            a.data = propValue;
        case 'index'
            a.index = propValue;
        otherwise
            error([propName, ' Is not a valid uiindexer property'])
    end
end
main/@uiindexer/get.m
Code :
1
2
3
4
5
6
7
8
9
10
11
function val = get(a, propName)
    propName = lower(propName)
    switch propName
        case 'datain'
            val = a.data;
        case 'index'
            val = a.index;
        otherwise
            error([propName, ' ...is not a valid uiindexer property'])
    end
end
main/main.m
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function main
    delete(timerfindall);
    global new_index;
    new_index = 0;
    data = [-5-5*i 5+5*i 3+i 0 -4+i -1-2*i -2-i];
    a = uiindexer('DataIn',  data, 'Callback', @aCallback)
    
    function aCallback % se déclenche dès qu'on clique sur un nouveau point du graphe OU BIEN dès qu'on "déplace" la sélection courante sur un nouveau point
        % Affichage de l'index :
        new_index 

        %%
        % ici, on a nos "data" et notre index "new_index"... l'utilisateur peut en faire ce qu'il veut, en temps réel !
        %%

    end
end
Il suffit d'exécuter le main pour faire un test rapide. Notez la simplicité d'utilisation...

Cordialement,
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 17h59   #14
Modérateur
 
Avatar de duf42
 
Homme
Formateur en informatique
Inscription : novembre 2007
Messages : 2 538
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2007
Messages : 2 538
Points : 3 253
Points : 3 253
Bonjour,

Je suis pas sûr que ce soit une bonne idée de nommer tes fonctions GET et SET: elles vont cacher les fonctions GET et SET de MATLAB ce qui peut entrainer des erreurs (c'est d'ailleurs le cas chez moi lorsque j'exécute ton MAIN).

De plus, je ne comprends pas bien pourquoi tu déclares des variables globales, surtout que tu ne les utilises pas (pas comme des variables globales en tous cas).

Duf
__________________
Modérateur MATLAB

Au boulot : Windows 7 , MATLAB 7.14 (r2012a)
A la maison : ArchLinux mais pas MATLAB
duf42 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 18h03   #15
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 oublié de virer cette variable globale (que je n'utilise pas) du main. J'étais en train d'updater, désolé.

Quelles erreurs tu as sur matlab ? J'utilise pourtant la méthode décrite par la doc officielle matlab (version R14SP3) pour définir set et get pour ses propres objets.

Cordialement,
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 18h05   #16
Modérateur
 
Avatar de duf42
 
Homme
Formateur en informatique
Inscription : novembre 2007
Messages : 2 538
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2007
Messages : 2 538
Points : 3 253
Points : 3 253
Désolé j'ai été un peu trop vite, je n'avais pas mis les fichiers dans l'arborescence correcte
__________________
Modérateur MATLAB

Au boulot : Windows 7 , MATLAB 7.14 (r2012a)
A la maison : ArchLinux mais pas MATLAB
duf42 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 18h06   #17
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
J'ai remis à jour (désolé) : en fait il y a bien besoin d'une global, mais sur new_index... T'en penses quoi ? De toutes façons, je revois tout ça demain, il se fait tard maintenant ^^

j'ai aussi rajouté "delete(timerfindall)" (parce que mon code n'est pas propre, les timers sont laissés ouverts ) au cas où tu réexecute plusieurs fois.
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 18h28   #18
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
Un Timer... pourquoi pas. Moi j'aurais juste mis dans la fonction myupdatefcn un appel à
Code :
this.Callback(new_indice)
Qui aurait fait passer la valeur du nouvel indice, sans besoin d'un global.

Pour les get/set à mettre en "interne" comme dans l'autre discussion (ma_fcn1 et ma_fcn2), ce qui donnerait quelque chose comme:
Code :
1
2
3
obj = uiindexer(...);
obj.set(...)
val = obj.get(...)
__________________
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 07/02/2012, 15h15   #19
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
[EDIT : ce message est long et est à moitié useless, et je conseille de passer directement au suivant... je laisse celui-ci car si quelqu'un trouve une solution, je suis quand même preneur.)

Bonjour,

Je galère... vous allez comprendre pourquoi :

Citation:
Envoyé par Winjerome Voir le message
Un Timer... pourquoi pas. Moi j'aurais juste mis dans la fonction myupdatefcn un appel à
Code :
this.Callback(new_indice)
Qui aurait fait passer la valeur du nouvel indice, sans besoin d'un global.
==> Ce n'est pas possible : quand on est dans la fonction myupdateFcn, on n'a pas accès à notre objet (this est inaccessible). Il suffit de rajouter :

Code :
1
2
3
disp('DEBUT')
this
disp('FIN')
pour le vérifier rapidement... (FIN devrait s'afficher à moment donné, mais ne le fait pas : il essaye d'accéder à "this", n'y arrive pas, mais n'affiche pas d'erreur, c'est le comportement de datacursormode qui ne l'a pas prévu).

Citation:
Envoyé par Winjerome Voir le message
Pour les get/set à mettre en "interne" comme dans l'autre discussion (ma_fcn1 et ma_fcn2), ce qui donnerait quelque chose comme:
Code :
1
2
3
obj = uiindexer(...);
obj.set(...)
val = obj.get(...)
Je voudrais bien le faire, mais le souci, c'est que j'ai décidé de créer ma fonctionnalité à la "sauce matlab"... donc je transforme ma structure this en "classe" avec :
Code :
this = class(this, 'uiindexer');
ce qui permet de faire fonctionner le tout à la sauce matlab, certes, mais ne permet donc plus d'accéder à des méthodes définies directement dans la structure. Si je n'arrive pas à faire fonctionner le tout à la sauce matlab, c'est ce que je ferais bien sûr.




Bon, j'ai recodé le tout pour que ce soit encore plus propre qu'avant, en suivant les consignes de la doc à la lettre, et.... ça foire toujours, of course. Voici le code actuel (remplace entièrement le précédent) :

../@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
function this = uiindexer(varargin)
% UIINDEX
    global internal_uiindexer_index
    internal_uiindexer_old_index = 0;
    internal_uiindexer_index = 0;
    function_callback = 0;
    this = struct(...
        'data',             0, ...
        'index',            [], ...
        'figure',           [], ...
        'axe',              0, ...
        'callback',         0);
    if nargin == 1 %% Copy constructor
        if (isa(varargin{1}, 'uiindexer'))
            this = varargin{1};
        else
            error('Wrong argument type.')
        end
    elseif mod(nargin, 2) == 1
        error('Wrong inputs. Admits only pairs of (property,value)')
    else
        if nargin == 0 %% Default constructor
            this.data = [-2-2*i 2+2*i -1+i 1+i 1-i -1-i];
            this.index = 3;
            this.figure = figure;
            this.axe = axes('parent', this.figure);
        end
        inputs = varargin;
        while length(inputs) >= 2
            prop = inputs{1};
            val  = inputs{2};
            inputs = inputs(3:end);
            switch lower(prop)
                case 'figure'
                    this.figure = val;
                case 'axe'
                    this.axe = val;
                case 'data'
                    this.data = val;
                case 'index'
                    disp('??? Warning ==> impossible to set "index" property')
                    this.index = [];
                case 'callback'
                    this.callback = val;
                    function_callback = val;
                otherwise
                    error(['The property "' num2str(prop) '" is not supported.'])
            end
        end
        if isempty(this.figure)
            this.figure = figure;
            this.axe = axes('parent', this.figure);
        end
        dcm_obj = datacursormode(this.figure);
        set(dcm_obj, 'enable', 'on', ...
            'snaptodatavertex', 'on', ...
            'displaystyle', 'datatip', ...
            'UpdateFcn', @updateIndex); %%%%% <- ICI je fais appel à ma fonction (en suivant les consignes de datacursormode)
        plot(this.axe, this.data, 'x');
        this = class(this, 'uiindexer');
    end

function txt = updateIndex(empt, event_obj)
    global internal_uiindexer_index
    pos = get(event_obj, 'Position');
    index = get(event_obj, 'DataIndex');
    if internal_uiindexer_index ~= index
        internal_uiindexer_index = index
        disp('MAJ "index"... ("FIN" doit apparaitre ci-dessous)')
        this = set(this, 'index', index);     %%%%%% <- ICI je voudrais mettre à jour mon index dans ma classe
        disp('FIN')                    %%%%%% <- FIN ! (mais ne marche pas pour l'instant à cause de la ligne précédente)
    end
    txt = {['Reel : ', num2str(pos(1))], ...
        ['Imag : ', num2str(pos(2))], ...
        ['Index :', num2str(index)]};
../@uiindexer/set.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
function this = set(this, varargin)
% SET Set uiindexer properties and return the updated object
inputs = varargin
while length(inputs) >=2
    prop = inputs{1};
    val = inputs{2};
    inputs = inputs(3:end);
    switch lower(prop)
        case 'figure'
            disp('Impossible to change figure: create new uiindexer for this pupose.')
        case 'axe'
            disp('Impossible to change axe: create new uiindexer for this pupose.')
        case 'index'
            this.index = val;
        case 'data'
            this.data = val;
            hold off
            this.index = [];
            plot(this.axe, this.data, 'x');
        otherwise
            error('Wrong arguments')
    end
end
../@uiindexer/get.m
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function val = get(this, prop)
% GET Get uiindexer properties from the specified object and return the
% value
switch lower(prop)
    case 'figure'
        val = this.figure;
    case 'axe'
        val = this.axe;
    case 'data'
        val = this.data;
    case 'index'
        if isempty(this.index)
            disp('Index undefined')
        elseif this.index == 0
            disp('Index undefined')
        end
        val = this.index;
    otherwise
        error(['"' prop '" is not a valid uiindexer property.'])
end
../@uiindexer/display.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
function display(this)
% DISPLAY(uiindexer_obj) Display an uiindexer object
disp(' ')
disp(['Properties:']);
disp('    data, index, figure*, axe*')
disp('* GET only or initialize on construction')
disp(' ');

disp([inputname(1) ' = '])
if (this.index == 0)
    disp(['    data:  ' num2str(this.data)])
    disp(['    index:  undefined'])
elseif isempty(this.index)
    disp(['    data:  ' num2str(this.data)])
    disp(['    index:  undefined'])
elseif this.index == 1
    disp(['    data:  ' ' [' num2str(this.data(1)) '] ' num2str(this.data(2:end))])
    disp(['    index: ' num2str(this.index)])
elseif this.index == length(this.data)
    disp(['    data:  ' num2str(this.data(1:this.index-1)) ' [' num2str(this.data(this.index)) '] '])
    disp(['    index: ' num2str(this.index)])
else
    disp(['    data:  ' num2str(this.data(1:this.index-1)) ' [' num2str(this.data(this.index)) '] ' num2str(this.data(this.index+1:end))])
    disp(['    index: ' num2str(this.index)])
end
disp(' ')
Pour le tester :
Vous pourrez remarquer mes commentaires à la fin du fichier uiindexer.m qui montre où est précisément mon problème. Lors de l’exécution, on constate bien que les lignes qui m'intéressent ne s’exécutent pas puisque "FIN" ne s'affiche pas (lors du clic sur un point du graphique). De plus, si vous faites un :
dans la console après avoir cliqué sur un point de la courbe, l'index reste bloqué à sa valeur par défaut (j'ai mis 3 pour le constructeur par défaut).

Cordialement,

ps: vous pouvez vous amuser à modifier les données d'entrées comme bon vous semble avec set ou directement lors de la définition en faisant "a=uiindexer('data', donnee_perso)" (donnee_perso étant un tableau de données à afficher) ou à l'implémenter dans la figure et l'axe de votre choix, etc...
tachmou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 16h37   #20
Membre du Club
 
Inscription : janvier 2012
Messages : 59
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 59
Points : 41
Points : 41
Bon,

En appliquant la méthode "Pseudo POO", ça marche, c'est beau, c'est rapide et ça marche... ah oui, et ça marche aussi. Ai-je spécifié que ça marche ?

Un seul fichier, pas de restriction sur le nom du répertoire :

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
function this = uiindexer(varargin)
% UIINDEX
    %% VARIABLES
    data = [];
    index = [];
    f = [];
    a = [];
    callback = [];
    this = struct(...
        'data',             @getData, ...
        'index',            @getIndex, ...
        'figure',           @getFigure, ...
        'axe',              @getAxe, ...
        'callback',         @setCallback);
    
    %% CONSTRUCTEURS
    if mod(nargin, 2) == 1
        error('Wrong inputs. Admits only pairs of (property,value)')
    else
        if nargin == 0 %% Default constructor
        end
        inputs = varargin;
        while length(inputs) >= 2
            prop = inputs{1};
            val  = inputs{2};
            inputs = inputs(3:end);
            switch lower(prop)
                case 'figure'
                    f = val;
                case 'axe'
                    a = val;
                case 'data'
                    data = val;
                case 'index'
                    disp('??? Warning ==> impossible to set "index" property')
                    index = 0;
                case 'callback'
                    callback = 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);
        end
        if isempty(callback)
            callback = 0;
        end
        dcm_obj = datacursormode(f);
        set(dcm_obj, 'enable', 'on', ...
            'snaptodatavertex', 'on', ...
            'displaystyle', 'datatip', ...
            'UpdateFcn', @updateIndex);
        plot(a, data, 'x');
    end
    
    function out = getIndex()
        out = index;
    end

    function setCallback(in)
        callback = in;
    end
    
    function txt = updateIndex(empt, event_obj)
        pos = get(event_obj, 'Position');
        index = get(event_obj, 'DataIndex');
        callback();
        txt = {['Reel : ', num2str(pos(1))], ...
            ['Imag : ', num2str(pos(2))], ...
            ['Index :', num2str(index)]};
    end
end
Utilisation :

Puis cliquez sur le graphique...

et récupérer l'index :

Oh miracle, ça marche, c'est puissant, c'est rapide, c'est intuitif, c'est simple...

Lors de la création, on peut spécifier la figure, l'axe et les données.

Bon, je vais rester avec cette fonction... au pire, peut-être que je l'implémenterai dans une classe façon matlab pour ne pas dépayser les utilisateurs "classiques" de matlab (donc set, get etc...). J'essaye pour l'instant de mettre un maximum de fonctionnalités.

Cordialement,

ps je suis de retour vendredi, pas avant.
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