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

GTK+ avec C & C++ Discussion :

ProgressBar et Fonction


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 34
    Par défaut ProgressBar et Fonction
    Bonjour après 2 jours de recherche infructueuse je me décide à demander de l'aide....

    Voici mon problème :

    Je désire suivre l'évolution d'une fonction par le biais d'une ProgressBar, la fonction en question est complètement externe à GTK, elle fait partie d'une de mes bibliothèque et peut être modifiée à ma guise.

    Pour lancer cette fonction j'utilise un bouton (dans ma fenetre principale), sont callback me permet de lancer une nouvelle fenêtre qui affiche la barre de progression et la fonction.

    Ma question est comment faire en sorte que ma fonction retourne régulièrement une valeur pour que la progressbar évolue ?

    J'ajoute un peu de code, en espérant que sa pourra aider à comprendre se que je veux faire.

    <CModule.h>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ///  declarations ....
    class CModule {
    protected:
    public:
          int m_iAvancement; 
          bool Fonction(data) ;
          bool ComputeAff(data);
          bool Compute(data);
    }
    <CModule.cpp>
    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
     
    ///  declarations ....
    bool ComputeAff(gpointer data)
    {
       ///// data une structure contenant  des pointeurs sur différents parametres et des Widget
       // La Fenetre
       data->pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       gtk_window_set_title(GTK_WINDOW(data->pWindow), "GtkProgressBar");
       gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 100);
       gtk_container_set_border_width(GTK_CONTAINER(data->pWindow), 4);
       // Le decoupage vertical
       GtkWidget * pMainVBox = gtk_vbox_new(TRUE, 0);
       gtk_container_add(GTK_CONTAINER(pWindow), pMainVBox);
       /* Creation de la barre de progression Principale*/
       data->pProgressP = gtk_progress_bar_new();
       gtk_box_pack_start(GTK_BOX(pMainVBox), data->pProgressP, TRUE, FALSE, 0);
       g_signal_connect(G_OBJECT(data->pWindow), "show",  G_CALLBACK(Compute), (gpointer*)data);
      gtk_widget_show_all(data->pWindow);
      gtk_main();
      return TRUE;
     }
     
    bool Compute (gpointer data)
    {
    ///// data une structure contenant  des pointeurs sur différents parametres et des Widget
     
    //// Initialisation de la progressbar (pas de pb)
     
    // Je veux lancer ma fonction
    CModule  core_module;
    core_module.m_iAvancement=0;  //fixe avancement à zéro et au cours de la fonction Avancement évolue.
     
    core_module. bool Fonction(data); // lancement de la function
     
    //// Comment faire évoluer la progressbar ?????
     
    }


    <Main.cpp>
    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
     
    ///  declarations ....
     
    void Callback_Lancement (GtkWidget* widget, gpointer data)
    {
         // Relayage vers FONCTION
         CModule().Compute(data);
    }
     
    void main()
    {
        /*********************
        * Initialisation GTK *
        *********************/
         //Init du multithreading
         if(!g_thread_supported())
             g_thread_init(NULL);
     
         //Init le multithreading pour GDK
         gdk_threads_init();
     
         //Zone critique du thread pour le programme principal
         gdk_threads_enter();
     
         /***************************
        * L'application principale *
        ***************************/
         //Taille de la fenetre principale
         int m_nSizeX = 200; int m_nSizeY = 100;
         //Cree la fenêtre
         GtkWidget* m_pWindowSecondaire = gtk_window_new(GTK_WINDOW_TOPLEVEL);
         p_struc_gtkpointer->p_Widget1 = m_pWindowSecondaire;
         //Fixe la taille de la fenêtre
         gtk_window_set_default_size(GTK_WINDOW(m_pWindowSecondaire),m_nSizeX,m_nSizeY);
         //Fixe l'affichage de la fenêtre au centre
         gtk_window_set_position(GTK_WINDOW(m_pWindowSecondaire),GTK_WIN_POS_CENTER);
         // Contenaire et ajout a la fenetre
         GtkWidget* m_pV = gtk_vbox_new(FALSE,0);
         gtk_container_add(GTK_CONTAINER(m_pWindowSecondaire),m_pV);
     
        ///// DIVERS WIDGET de RéGLAGES
     
         /// Boutton APPLIQUER
         GtkWidget* pApply=gtk_button_new_from_stock(GTK_STOCK_EXECUTE);
         gtk_box_pack_start(GTK_BOX(m_pV),pApply,FALSE,FALSE,0);
         /// Lance calcul 
         g_signal_connect(G_OBJECT(pApply),"clicked",G_CALLBACK(Callback_Lancement),(gpointer*)data);
     
         //Affichage principal
         gtk_widget_show_all(m_pWindowSecondaire);
         //Entre dans la boucle infinie
         gtk_main();
         //Fin de la zone critique du thread du programme principal
         gdk_threads_leave();
    }

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Fonction (data); doit obligatoirement être capable de donner une information en temps réel sur sa progression si tu tiens à avoir une valeur de la barre de progression précise.

    Si Fonction (data); ne peut pas le faire tu peux simplement utiliser la barre de progression en mode automatique. La barre se déplace de gauche à droite indéfiniment tant que tu ne la détruit pas.

    Quelque soit la solution choisie le principe est d'utiliser g_timeout_add(); (ou dérivée) pour ajouter une fonction annexe à la boucle principale Gtk. Cette fonction annexe gère exclusivement la barre de progression. Avec cette méthode ton interface n'est pas figée. Tu pourras donc interrompre l'exécution de Fonction (data); à tout moment (ou autre chose...).

  3. #3
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par gerald3d Voir le message

    Quelque soit la solution choisie le principe est d'utiliser g_timeout_add(); (ou dérivée) pour ajouter une fonction annexe à la boucle principale Gtk. Cette fonction annexe gère exclusivement la barre de progression. Avec cette méthode ton interface n'est pas figée. Tu pourras donc interrompre l'exécution de Fonction (data); à tout moment (ou autre chose...).
    Hop hop hop, tu vas un peu vite. Si sa fonction est une fonction qui a un temps d'exécution non négligeable, alors g_timeout_add ou ses dérivés ne fonctionnera tout bonnement pas, il sera obligé de passer par un thread. Tout traitement effectué dans des callbacks bloque la pompe à événements de GTK. Pour s'en rendre compte, il suffit de faire un appel à sleep(5) par exemple, pour simuler une fonction qui met 5 secondes à s'exécuter et rendre la main. Le thread principal gère l'interface graphique, donc si tu le bloques pendant 5 secondes, ton application est figée. S'il n'y a pas de variante asynchrone à sa fonction, il est obligé d'utiliser un thread.

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par liberforce Voir le message
    Hop hop hop, tu vas un peu vite. Si sa fonction est une fonction qui a un temps d'exécution non négligeable, alors g_timeout_add ou ses dérivés ne fonctionnera tout bonnement pas, il sera obligé de passer par un thread. Tout traitement effectué dans des callbacks bloque la pompe à événements de GTK. Pour s'en rendre compte, il suffit de faire un appel à sleep(5) par exemple, pour simuler une fonction qui met 5 secondes à s'exécuter et rendre la main. Le thread principal gère l'interface graphique, donc si tu le bloques pendant 5 secondes, ton application est figée. S'il n'y a pas de variante asynchrone à sa fonction, il est obligé d'utiliser un thread.
    Oui tout à fat d'accord Liberforce . Je ne cherchais qu'à apporter une première solution généraliste. Maintenant si son process est gourmand en temps, un passage par les threads sera nécessaire.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 34
    Par défaut
    Merci de vous intéresser à mon problème. Effectivement le passage par les threads me parait obligatoire car la fonction peut durer plusieurs minutes. Par contre je ne vois pas comment m'y prendre les tutos ne sont pas nombreux ....

    J'ai essayé cette méthode :

    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
     
    bool Compute (gpointer data)
    {
    ///// data une structure contenant  des pointeurs sur différents parametres et des Widget
     
    //// Initialisation de la progressbar (pas de pb)
     
    // Je veux lancer ma fonction dans un thread
     
    g_thread_init (NULL);
    GThread          *Thread1;
    char *message1 = "Thread 1";
    GError           *err1 = NULL ;
     
    if( !g_thread_supported() )
    {
        g_thread_init(NULL);
        gdk_threads_init();                
        printf("g_thread supported\n");
    }
    else
    {
        printf("g_thread NOT supported\n");
    }
     
     
    CModule  core_module;
    core_module.m_iAvancement=0;  //fixe avancement à zéro et au cours de la fonction Avancement évolue.
     
    if( (Thread1 = g_thread_create((GThreadFunc) core_module.Fonction(data),  (void *)message1, TRUE, &err1)) == NULL)
    {
        printf("Thread create failed: %s!!\n", err1->message );
        g_error_free ( err1 ) ;
    }
     
    g_thread_join(Thread1);
     
     
    //// Comment faire évoluer la progressbar ?????
     
    }
    Le premier problème, à l'exécution j'ai systématiquement "g_thread NOT supported" ??

    Ensuite, malgré tout la fonction est lancé mais plante au bout d'une petit moment. (Lors de l’exécution de : g_thread_join(Thread1)

    De plus je ne sait toujours pas comment récupérer en même temps la variable Avancement n'i mettre à jours m'a progressbar.

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Tout d'abord g_thread_init(); n'est plus nécessaire :
    The GLib threading system used to be initialized with g_thread_init(). This is no longer necessary. Since version 2.32, the GLib threading system is automatically initialized at the start of your program, and all thread-creation functions and synchronization primitives are available right away.
    Ensuite il faut bien faire attention lorsqu'on manipule des threads. Les variables globales sont automatiquement boquées lors de leur accession à contrario des variables locales. message1 par exemple peut poser problème. L'utilisation des GMUTEX devient alors obligatoire.

    En utilisant un debogueur (gdb par exemple) tu pourrais avoir une information plus fine sur le lieu où le crash se produit.

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

Discussions similaires

  1. afficher une ProgressBar pour une fonction
    Par bullrot dans le forum C#
    Réponses: 6
    Dernier message: 06/06/2012, 11h15
  2. Réponses: 1
    Dernier message: 19/01/2010, 14h48
  3. Réponses: 1
    Dernier message: 14/04/2008, 11h23
  4. Réponses: 1
    Dernier message: 13/04/2008, 14h53
  5. [MFC] fonction Create d'une ProgressBar
    Par lastcheper dans le forum MFC
    Réponses: 10
    Dernier message: 20/05/2005, 15h20

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