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 :

GUI & Timer => problème d'handle sur la figure


Sujet :

Interfaces Graphiques

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut GUI & Timer => problème d'handle sur la figure
    Bonjour à tous,

    Bien que connaissant Matlab depuis un certaine temps deja, je me suis mis récemment à la prog avec GUIDE, sous une matlab 7.5 2007b.

    Actuellement je suis sur un projet ou je dois interfacer une appareil de mesure type impédance mètre (Agilent 4294A pour ceux que ca intéresse) tout cela grace au port GPIB de l'appareil. Donc pour le moment, j'arriver bien à commander et récupérer les données de l'appareil, ce qui est deja un bon début. Mais actuellement, pour lancer une série de mesure, je suis obligé de cliquer sur un bouton, et j'aimerais automatiser cette tache par le biais d'un timer.

    J'ai donc chercher à faire un timer, qui aura une callback, appelant les fonctions callback "classiques" qui sont reliées à mes boutons. Donc je me suis crée un nouveau bouton "timer" qui créer un timer MATLAB, je lui passe une fonction callback, et je le start(). Jusque la tout marche bien, il rentre dans la callback, effectue une première série de mesure, et attend une période (je suis en mode fixedDelay).

    Maintenant mon problème est que lorsqu'il repasse dans cette callback, il fait nimporte quoi : il ouvre une nouvelle figure(), me met ses données dedans... Donc j'ai pensé que c'etait un problème de handle de ma zone d'axes, donc j'ai essayé de lui filer tous les gcf, gca que je pensais possible, mais apparement pas.

    Je viens donc à vous pour trouver une solution, car il semble que je ne passe pas les bonnes données à ma fonction timer_callback. Pour simplifier la démo, comme j'imagine que pas tout le monde a un appareil à 40k$ chez lui, j'ai fait un programme minimaliste à partir d'un code que j'ai récupéré ici, et écrit par DUT qui semble maitriser totalement l'art du matlabisme, pour info, il provient de ce fil : http://www.developpez.net/forums/sho...d.php?t=444275.

    Je l'ai adapté pour que le bouton "plot" fasse un plot de 10 points au hasard, et que le bouton timer démarre un timer qui est sensé appelé le bouton "plot" toutes les 2 secondes... Le code est très simpliste, et les boutons pas du tout au bon endroit. Et plus drole encore, il n'arrive pas à faire marcher le "plot" plus d'une fois car il ne retrouve pas les bonnes infos pour afficher : Error using ==> guidata at 89. H must be the handle to a figure or figure descendent.

    voila le code du fichier matlab :

    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
     
    function test_timer
     
    fig=figure;
     
    axes('tag','myAxes','visible','on')
     
    uicontrol('units','normalized',...
        'position',[.02 .2 .1 .05],...
        'string','Timer',...
        'tag','selectbutton',...
        'callback', @timerBT)
     
    uicontrol('units','normalized',...
        'position',[.02 .3 .1 .05],...
        'string','Plot',...
        'tag','displaybutton',...
        'callback', @plotBT)
     
    h=guihandles(fig);
    guidata(fig,h);
     
    function timerBT(obj,event)
    h=guidata(gcbf);
    h.timer = timer();
    set(h.timer, ...
                'TimerFcn', {@timerCB, gcbf}, ...
                'Period', 2, ...
                'ExecutionMode', 'fixedSpacing');
    start(h.timer);
     
    function timerCB(obj,event, handles)
    h=guidata(handles);
    plotBT(obj, event)
    hold on;
     
    function plotBT(obj,event)
    h=guidata(gcbf);
    axes(h.myAxes);
    plot(rand(10, 1), rand(10, 1))
    hold on;
    Merci pour votre aide, car ca fait 2 jours que je suis la-dessus sans avoir avancer d'un pas...

    A++

    Xavier

    EDIT/PS : j'oubliais, c'est mon premier message ici, donc si j'ai fait une erreur sur la facon de poster, merci d'avance de m'expliquer quoi et de me le pardonner ^^

  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 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Comme ceci :

    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
    function test_timer
     
    fig=figure('tag','myfig');
     
    axes('tag','myAxes','visible','on')
     
    uicontrol('units','normalized',...
        'position',[.02 .2 .1 .05],...
        'string','Timer',...
        'tag','selectbutton',...
        'callback', @timerBT)
     
    uicontrol('units','normalized',...
        'position',[.02 .3 .1 .05],...
        'string','Plot',...
        'tag','displaybutton',...
        'callback', @plotBT)
     
    h=guihandles(fig);
    guidata(fig,h);
     
    function timerBT(obj,event)
    h=guidata(gcbf);
    h.timer = timer();
    set(h.timer, ...            'TimerFcn', {@timerCB, gcbf}, ...
                'TimerFcn', @plotBT, ...
                'Period', 2, ...
                'ExecutionMode', 'fixedSpacing');
    start(h.timer);
     
    guidata(gcbf,h)
     
    % function timerCB(obj,event, handles)
    % h=guidata(gcbf);
    % plotBT(obj, event)
    % hold on;
     
    function plotBT(obj,event)
     
    h=guidata(gcf);
    % ou
    % fig=findobj('tag','myfig');
    % h=guidata(fig);
     
    axes(h.myAxes);
    plot(rand(10, 1), rand(10, 1))
    hold on;
    L'exemple reste bien entendu très simpliste. Dans ton cas réel, il y aurait peut être d'autres interactions à prendre en compte

    Note : si tu veux un meilleur controle sur ton interface, je ne peux que te conseiller de ne pas trop utiliser le GUIDE... => Introduction à la programmation des interfaces graphiques

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Re,

    Effectivement, j'avais vu que ca marchait bien comme ca, mais je ne peux pas vraiment retenir cette solution, car j'ai besoin de passer par une fonction "intermédiaire". Le timer appelle cette fonction, qui fait son petit boulot et change 2-3 trucs dans l'interface, et appelle ensuite le bouton. Le problème est que la fonction intermédiaire semble "perdre" les infos sur les variables de l'interface.

    Cela dit, je peux essayer de tout mettre dans le champ de 'timerFcn', mais ca me parait bizarre que l'on ne puisse pas passer par une fonction callback du timer sans perdre la partie GUI, au niveau de la modularité du code j'aurais préféré cette solution,

    Merci pour cette réponse et pour avoir mis mon post dans la bonne section,

    Xavier

  4. #4
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Comme ceci alors ?

    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
    function test_timer
     
    fig=figure('tag','myfig');
     
    axes('tag','myAxes','visible','on')
     
    uicontrol('units','normalized',...
        'position',[.02 .2 .1 .05],...
        'string','Timer',...
        'tag','selectbutton',...
        'callback', @timerBT)
     
    uicontrol('units','normalized',...
        'position',[.02 .3 .1 .05],...
        'string','Plot',...
        'tag','displaybutton',...
        'callback', @plotBT)
     
    h=guihandles(fig);
    guidata(fig,h);
     
    function timerBT(obj,event)
    h=guidata(gcbf);
    h.timer = timer();
    set(h.timer, ...            
                'TimerFcn', @timerCB, ...
                'Period', 2, ...
                'ExecutionMode', 'fixedSpacing');
    start(h.timer);
     
    guidata(gcbf,h)
     
    function timerCB(obj,event, handles)
    h=guidata(gcf);
    % ou
    % fig=findobj('tag','myfig');
    % h=guidata(fig);
     
    clc
    get(h.myfig) % Pour vérification
     
    plotBT([], [])
    % hold on;
     
    function plotBT(obj,event)
     
    h=guidata(gcf);
    % ou
    % fig=findobj('tag','myfig');
    % h=guidata(fig);
     
    axes(h.myAxes);
    plot(rand(10, 1), rand(10, 1))
    hold on;

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Salut,

    Ca marche parfaitement bien, mais je ne suis vraiment pas sur d'élément détreminant qui a tout changé Bon maintenant le dernier problème c'est de donner les bons arguments. La fonction plotBT(obj, event) provient de GUIDE, donc c'est plutot un plotBT(hObject, eventdata, handles). J'ai bien lu tes tutos, et je commence à comprendre le(s) problème(s), mais j'ai plus trop le temps de recoder à la mano les positions de mon interface. J'ai une 10 aines de boutons, 4 axes, des labels... bref trop de truc à recoder pour dire que je dois rendre un version "fonctionnelle" vendredi prochain

    Donc qu'est-ce qu'il faudrait que je passe à l'appel de ma fonction
    pour la tranformer en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    plotBT(hObject, eventdata, handles)
    Est-ce que tu as une idée sur ce point ?

    Merci encore, maitenant je sais que si le codage de l'interface est plus dur sans le .fig, et bien le code est plut joli. J'ai d'ailleurs trouvé assez bizarre l'utilisation d'un singleton dans le .m généré automatiquement, mais à l'époque j'avais pensé que les informaticiens de Matlab devait s'y connaitre mieux que moi pour faire du code "simple et beau" ^^

    A++

    Xavier

  6. #6
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    De quel(s) argument(s) as-tu besoin pour la fonction plotBT ?

    handles très certainement... hObject peut être... eventdata certainement pas...

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    hObject en principe pas, si j'ai bien compris, il s'agit d'un handle sur l'objet de la fonction qui est appelée (le bouton qui a été cliqué)

    event pas implémenté, donc je dirai plutot handles, pour pouvoir accéder aux handles des zones de dessins de mon interface...

  8. #8
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Dans ton cas, l'argument handles n'est pas vraiment nécessaire, puisqu'il peut être facilement retrouvé à l'aide de la fonction GUIDATA. De plus, maitriser cette fonction permet de bien mieux contrôler l'évolution des variables dans le code.

    handles et h sont identiques dans plotBT.

    Par exemple :
    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
    function test_timer
     
    fig=figure('tag','myfig');
     
    axes('tag','myAxes','visible','on')
    title('Nombre de tracé : 0')
     
    uicontrol('units','normalized',...
        'position',[.02 .2 .1 .05],...
        'string','Timer',...
        'tag','selectbutton',...
        'callback', @timerBT)
     
    uicontrol('units','normalized',...
        'position',[.02 .3 .1 .05],...
        'string','Plot',...
        'tag','displaybutton',...
        'callback', @plotBT)
     
    h=guihandles(fig);
    h.numTrace=0;
     
    guidata(fig,h);
     
    function timerBT(obj,event)
    h=guidata(gcbf);
    h.timer = timer();
    set(h.timer, ...            
                'TimerFcn', @timerCB, ...
                'Period', 2, ...
                'ExecutionMode', 'fixedSpacing');
    start(h.timer);
     
    guidata(gcbf,h)
     
    function timerCB(obj,event, handles)
    h=guidata(gcf);
    % ou
    % fig=findobj('tag','myfig');
    % h=guidata(fig);
     
    plotBT([], [])
    % hold on;
     
    function plotBT(obj,event)
     
    h=guidata(gcf);
    % ou
    % fig=findobj('tag','myfig');
    % h=guidata(fig);
     
    axes(h.myAxes);
    plot(rand(10, 1), rand(10, 1))
     
    h.numTrace=h.numTrace+1;
    title(sprintf('Nombre de tracé : %d',h.numTrace));
     
    hold on;
     
    guidata(gcf,h);
    Note : il y a un petit décalage du nombre de tracé à cause du timer

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Salut,

    J'ai du mal à comprendre, je pense que Matlab m'aime pas , j'ai essayé de refaire la même chose avec h=guidata(gcf); dans un code de test dans GUIDE, mais ca ne marche toujours pas, donc peut-être que c'est moi ou alros il y a un pb avec Matlab, mais avant de tout lacher et de partir sur ton idée de définir tout à la main, j'aimerais savoir si ca ne marche vraiment pas avec GUIDE.

    J'ai mis mon code "test_timer.m" et "test_timer.fig" dans un .zip Normalement le bouton "plot" marche bien, et quand on test le bouton "timer", ca marche la première fois et ensuite ca ouvre une nouvelle figure...

    Merci de vos lumières,

    Xavier
    Fichiers attachés Fichiers attachés

  10. #10
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Le problème vient de la propriété HandleVisibility de l'objet Figure.

    Par défaut, cette propriété est mise à "Callback" par le GUIDE et cela provoque des interférences avec l'objet Timer.

    Il faut, dans le GUIDE, mettre la propriété HandleVisibilty de l'objet Figure à "On".

    C'est expliqué ici : Why does a PLOT command in the timer function generate a new figure without plotting into the existing GUI?

    Pas besoin de tout recoder à la main... cette fois-ci

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut MERCI BEAUCOUP !!!!
    Re,

    Et ben voila, problème résolu apparemment. Merci infiniment pour ton aide ! Je pense pas que j'aurais réussi à trouver cela sans toi. Dire que je trainais autour de ce problème tout ca à cause de ce "*%"ç* de petit paramètre

    Cela dit je trouve bizarre que j'ai pas trouvé la page que tu mentionnes... J'ai fait des recherches google avec "figure matlab timer callback"... mais sans rien trouver de probant. Enfin bref, tout est bien qui fini bien.

    Je met le post en résolu, et j'espère que mon problème pourra aider d'autres codeurs, la solution était loin d'être évidente...

    A bientot,

    Xavier

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

Discussions similaires

  1. Problème d'échelle sur les figures
    Par helaaa dans le forum MATLAB
    Réponses: 1
    Dernier message: 16/08/2010, 18h05
  2. Problème avec 'light' sur un patch dans un GUI
    Par pierolapuree dans le forum Interfaces Graphiques
    Réponses: 1
    Dernier message: 16/02/2007, 14h35
  3. [CR] Problème de sélection sur un champ date
    Par noluc dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 21/11/2003, 16h56
  4. Problème avec RDTSC sur K6-III
    Par le mage tophinus dans le forum x86 32-bits / 64-bits
    Réponses: 17
    Dernier message: 30/09/2003, 09h43
  5. problème de float sur SQL server 2000.
    Par fidji dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 24/07/2003, 14h15

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