Mise à jour progressbar

Résolu
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008 - 5 oct. 2008 à 11:02
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 - 8 oct. 2008 à 00:09
Bonjour,

Je m'amuse actuellement à programmer un logiciel qui permet d'apprendre du vocabulaire. Pour cela mon application pioche un mot dans une base de donnée, attend une traduction et vérifie si le mot entré est juste. A chaque fois que l'utilisateur répond juste pour la traduction du mot une progressbar s'incrémente.

ex : Interrogation ==> mise a jour de la progress bar en fonction du nombre précédent de réponses justes ==> réponse utilisateur juste ou fausse ==> incrémentation ou non de la progress bar ==> interrogation autre mot .....

Mon problème vient du fait que le code pour incrémenter la progressbar s'exécute (pas de plantage et je constate que la valeur à incrémenter à bien été augmentée) mais la progress bar ne se met pas a jour une fois le mot saisi et validé. Je ne constate qu'elle est a jour seuleument lorsque le mot m'es soumis une seconde fois ...

J'utilise la fonction suivante pour mettre a jour : pgrb_mot.Value = nouvelle_valeur

Peut-être y a t-il moyen de forcer l'affichage de cette barre ... Si quelqu'un pouvait m'aider ? :)

(Je programme sous VB 2008)

10 réponses

Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
7 oct. 2008 à 03:18
Ok, donc si je comprend bien, tout fonctionne comme ça devrait

Pour la tempo, utilise un timer:
Lorsque l'utilisateur valide le mot qu'il a entré, tu affiche le résultat (vrai/faux, ProgressBar) et tu lance le timer (par exemple 5 secondes)
Lors du Timer_Tick, tu désactive le timer, tu sélectionne le nouveau mot à traduire et tu met l'affichage à jour.

Un Sleep ne fonctionne pas car cela arrête ton thread, et donc la mise à jour de l'affichage ne se fait plus. A la limite une boucle avec un DoEvents et un Sleep pourrait aller, mais c'est franchement pas élégant. Ca donne ceci:

   Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
        If e.KeyCode = Keys.Enter Then

            If Corrige(TextBox1) Then
                ' Correct
                ListeMot(NumMot).NbJuste += 1
                ListeMot(NumMot).ProgressMot += 1

                pgrb_mot.Value = ListeMot(NumMot).ProgressMot
                lbl_correction.Text = ""

                Timer1.Start()
            Else
                ' Faux
                ListeMot(NumMot).NbFaux += 1
                ListeMot(NumMot).ProgressMot += 1

                pgrb_mot.Maximum = 5
                pgrb_mot.Value = ListeMot(NumMot).ProgressMot
                lbl_correction.Text = ListeMot(NumMot).nom2

            End If

        End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Timer1.Stop()
        TextBox1.Text = ""

        Call Interro()
        If ListeMot(NumMot).NbFaux = 0 Then
            pgrb_mot.Maximum = 3
        Else
            pgrb_mot.Maximum = 5
        End If

        pgrb_mot.Value = ListeMot(NumMot).ProgressMot
        lbl_interro.Text = ListeMot(NumMot).nom1

    End Sub
3
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
5 oct. 2008 à 12:02
Bonjour,

c'est le code de ta validation (toute la procédure) qu'il nous faut voir !
Juste une idée (avec boule de crystal) :
ordre chronologique :
1) apréciation de la validité de la réponse
2) mise à jour de ta variable nouvelle-valeur
3) mise à jour de la valeur de ta progressbar

(tout me donne à penser qu'au lieu de faire 1) puis 2) puis 3), tu fais 1), puis 3) puis 2) ===>> alors évidemment ...!!!

Un commentaire : je ne comprends pas l'utilité d'une variable nouvelle_valeur dont la valeur serait (double emploi, donc) celle déjà contenue dans la progressbar ...
0
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008
5 oct. 2008 à 13:00
Bonjour, voici le code qui est utilisé :

'Tout démarre avec l'appui sur la touche entrée d'un TextBox   

'Quelques définitions:

'@theme est un type sujet
'Structure sujet
'    Dim titre As String
'    Dim nbmots As Integer
'    Dim progresssujet As Integer
'    Dim listemot() As mot
'    Dim nummot As Integer
'    Dim termine As Integer Nombre qui une fois a nbmots indique que
'End Structure

'Structure mot
'    Dim nom1 As String
'    Dim nom2 As String
'    Dim com As String
'    Dim nbjuste As Integer
'    Dim nbfaux As Integer
'    Dim progressmot As Integer
'    Dim appri As Boolean
'End Structure

'@pgrb est la progressbar utilisée

'la fonction corrige renvoie seuleument un booleen vrai ou faux en 'fonction de la véracité du mot saisi.
'la fonction interro renvoir simplement un nouveau numéro d'index qui correspondra au nouveau mot demandé

Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
        If e.KeyCode = 13 Then 'code ascii correspondant a la touche entrée

            If corrige(TextBox1) = True Then 'REPONSE JUSTE

                'Mise a jour des paramètres du tableau en mémoire
                theme.listemot(theme.nummot).nbjuste = theme.listemot(theme.nummot).nbjuste + 1
                theme.listemot(theme.nummot).progressmot = theme.listemot(theme.nummot).progressmot + 1

                'Mise a jour des paramètres de l'interface (QUI NE SE FAIT PAS)
                pgrb_mot.Value = theme.listemot(theme.nummot).progressmot
                lbl_correction.Text = ""

            Else'REPONSE FAUSSE
                'Mise a jour des paramètres du tableau en mémoire
                theme.listemot(theme.nummot).nbfaux = theme.listemot(theme.nummot).nbfaux + 1
                theme.listemot(theme.nummot).progressmot = 0

                'Mise a jour des paramètres de l'interface (QUI NE SE FAIT PAS)
                pgrb_mot.Maximum = 5
                pgrb_mot.Value = theme.listemot(theme.nummot).progressmot

lbl_correction.Text = theme.listemot(theme.nummot).nom2

                GoTo motfaux

            End If

            TextBox1.Text = ""
            ToolStripProgressBar1.Value = theme.termine

            Call Sleep(700)
            '**********************************************************************

            'Redefinition du nouveau mot a apprendre
            Call Interro()

            'Choix de la larguer de la progress bar et de l'avancement (ICI LA MISE A JOUR FONCTIONNE)
            If theme.listemot(theme.nummot).nbfaux = 0 Then
                pgrb_mot.Maximum = 3
            Else
                pgrb_mot.Maximum = 5
            End If

            pgrb_mot.Value = theme.listemot(theme.nummot).progressmot

            lbl_interro.Text = theme.listemot(theme.nummot).nom1

        End If

motfaux:

    End Sub
0
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008
5 oct. 2008 à 13:03
J'avais également intercalé un sleep comme vous pouvez le voir, cela pour être sûr que la progresse bar ne se rafraichissait pas trop rapidement avec la valeur du prochain mot... Mais apparement cela ne marche pas.

En tout cas merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
5 oct. 2008 à 17:34
Salut,
Ca me semble un peu compliqué ton utilisation des structures....
L'incrémentation du nombre de réponses correctes doit se faire dans la structure sujet, pas mot. Ici tu incrémente une variable dans mot, alors que cette structure mot n'est plus utilisé pour le prochain mot (et donc vaut 0 pour le prochain mot)
0
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008
5 oct. 2008 à 20:51
Désolé, je comprend pas bien ce que tu me dis...

En ce qui concerne la structure mot, je l'incrémente après chaque réponse de l'utilisateur. Une fois que l'incrémentation atteint une valeur que j'ai préalablement décidé (l'utilisateur a donc répondu juste un certain nombre de fois), je considère que l'utilisateur connait ce mot. Enfin je ne pense pas avoir de problème avec ma structure car elle semble fonctionner.

J'ai juste un problème avec ma progress bar qui malgré le fait de prendre la bonne valeur (pgrb.Value a bien changé entre une question et une autre) n'augmente pas sa barre juste après la saisie de l'utilisateur comme je le voudrai.

Si jamais je passe à coté d'un truc n'hésite pas à me corriger. Merci
0
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
6 oct. 2008 à 02:36
Ouais désolé, il est vrai que ce n'est pas très compréhensible ce que j'ai dis avant
Mais j'avais pas vraiment compris le problème... et mtn je ne comprend pas pourquoi ça ne fonctionne pas....

Theme.ListeMot(Theme.NumMot).ProgressMot = 0
pgrb_Mot.Value = Theme.ListeMot(Theme.NumMot).ProgressMot

Clair que si tu exécute ces 2 lignes de code que que la valeur de prgb_Mot ne vaut pas 0, il y a un problème.
Qu'en est-il de la valeur dans Theme.ListeMot(Theme.NumMot).ProgressMot, vaut-elle bien 0?
0
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008
6 oct. 2008 à 09:14
Bonjour,

Ce bout de code que tu me donnes et ce qui se passe au cas ou l'utilisateur répond faux. Dans ce cas, en exécutant la méthode pas à pas je vois qu'en sortant de TextBox1_KeyDown la pgrb est revenu à 0. Donc oui la valeur de la progress bar passe bien a 0.

En voyant ça j'avais supposé que je ne voyais pas la progress bar s'incrémenter lorsque je répondais juste car vb allait trop vite et m'avais déjà affiché la progress bar correspondant au prochain mot qui sera soumis à l'utilisateur. C'est pour cela que j'ai insérer un Sleep afin de pouvoir voir l'augmentation de la progress bar, mais ca ne semble pasmarcher ...
0
SeKo54 Messages postés 18 Date d'inscription vendredi 28 mars 2008 Statut Membre Dernière intervention 5 novembre 2008
7 oct. 2008 à 19:46
Héhé, OK ça m'a généré pas mal d'erreurs, et maintenant mon programme plante  mais c'est normal j'ai insérer ton bout de code comme un barbare (en plus mon code est un peu plus complexe que ce que j'ai posté ...)

Mais bon le principal : ca fonctionne, je vois bien la barre s'incrémenter. Merci à toi, je connaissais pas l'objet timer. Par contre tu peux m'expliquer un peu plus la différence entre le timer et la fonction sleep ? Je suppose que "arreter ton thread" signifie bloquer tout le programme en cours (y compris l'affichage) mais bon l'appel à sleep étant placé avant le nouvel appel à "Interro" je pensais que la mise à jour de l'interface aurait été faite avant ...
0
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
8 oct. 2008 à 00:09
Ouais mon code était pour te montrer l'idée. Même si j'ai utilisé le même principe que ton code (par ex ListeMot), fallait pas compter sur un copier-coller 100% fonctionnel
Tu peux y voir qq trucs utiles du langage, par exemple
ListeMot(NumMot).NbJuste += 1
est la même chose que
ListeMot(NumMot).NbJuste = ListeMot(NumMot).NbJuste + 1

"Je suppose que "arreter ton thread" signifie bloquer tout le programme
en cours (y compris l'affichage)"

Exact. Un Sleep suspend l'exécution de ton programme (ou plus précisément le thread, mais dans une simple application utilisant 1 seul thread comme la tienne, cela revient donc au même).
Dans une application Win32, l'affichage se met à jours lorsque plus aucun code ne s'exécute dans ton application, ce qui n'est pas le cas lorsque tu passe 2 secondes dans un Sleep. La fonction DoEvents par contre, interrompt l'exécution de ton code et permet aux événements en attente de s'exécuter, ce qui inclut les mises à jour de l'affichage.

Un Timer, lui, n'empeche pas l'exécution de ton code. Il s'agit simplement d'une temporisation qui s'exécute dans un thread en arrière-plan, ce qui permet à ton prgramme de continuer de s'exécuter normalement. Une fois la temporisation écoulé, le timer appel l'événement Tick.

"mais bon l'appel à sleep étant placé
avant le nouvel appel à "Interro" je pensais que la mise à jour de
l'interface aurait été faite avant ..."

Ton code aurait pu fonctionner si tu avais mis un DoEvents juste avant le Sleep, ce qui aurait mis à jour l'affichage juste avant de suspendre le thread. Mais un Sleep, vu qu'il suspend l'exécution de ton programme, fait que ton application ne répond plus, ce qui par exemple provoque l'affichage de "Ne répond pas" dans la barre de titre et empêche tout le reste de fonctionner. La solution avec le Timer est bien meilleur.
0
Rejoignez-nous