[wxpython] problème avec les barres de progressions
5 réponses
Jerome
Bonjour
Un problème avant le week-end...
Soit le programme
import wx
class Win(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
s=wx.BoxSizer(wx.VERTICAL)
self.gauge = wx.Gauge(self, -1, 100)
b = wx.Button(self, wx.ID_OK)
self.Bind(wx.EVT_BUTTON, self.OnOk, b)
s.AddMany([self.gauge,b])
self.SetSizerAndFit(s)
self.Show(True)
def OnOk(self, evt):
for i in range(100):
for t in range(10000):
t=t*222**0.89
print i
self.gauge.SetValue(i)
app = wx.PySimpleApp()
frame=Win()
app.MainLoop()
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande
m'affiche progressivement les print i. Mais la "gauge" elle ne se met à
jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100
instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas
lancer un thread pour faire ça ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
tiissa
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande m'affiche progressivement les print i. Mais la "gauge" elle ne se met à jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100 instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres l'incrementation semblerait faire l'affaire.
Ensuite il faut voir si on veut vraiment la redessiner apres chaque calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement la possibilite de mettre en place un alarme pour executer une fonction regulierement.
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande
m'affiche progressivement les print i. Mais la "gauge" elle ne se met à
jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100
instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas
lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme
de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres
l'incrementation semblerait faire l'affaire.
Ensuite il faut voir si on veut vraiment la redessiner apres chaque
calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement
la possibilite de mettre en place un alarme pour executer une fonction
regulierement.
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande m'affiche progressivement les print i. Mais la "gauge" elle ne se met à jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100 instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres l'incrementation semblerait faire l'affaire.
Ensuite il faut voir si on veut vraiment la redessiner apres chaque calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement la possibilite de mettre en place un alarme pour executer une fonction regulierement.
fraca7
def OnOk(self, evt): for i in range(100): for t in range(10000): t=t*222**0.89 print i self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
def OnOk(self, evt):
for i in range(100):
for t in range(10000):
t=t*222**0.89
print i
self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements
de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour
incrémenter la valeur à intervalles réguliers.
def OnOk(self, evt): for i in range(100): for t in range(10000): t=t*222**0.89 print i self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
Jerome
fraca7 wrote:
def OnOk(self, evt): for i in range(100): for t in range(10000): t=t*222**0.89 print i self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification de la valeur d'un widget génère un événement pour qu'il actualise son affichage. Apparement ça ne le fait pas.
Par contre, le code que j'ai posté fonctionne sous windows :-(
fraca7 wrote:
def OnOk(self, evt):
for i in range(100):
for t in range(10000):
t=t*222**0.89
print i
self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements
de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour
incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification
de la valeur d'un widget génère un événement pour qu'il actualise son
affichage. Apparement ça ne le fait pas.
Par contre, le code que j'ai posté fonctionne sous windows :-(
def OnOk(self, evt): for i in range(100): for t in range(10000): t=t*222**0.89 print i self.gauge.SetValue(i)
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification de la valeur d'un widget génère un événement pour qu'il actualise son affichage. Apparement ça ne le fait pas.
Par contre, le code que j'ai posté fonctionne sous windows :-(
Jerome
wrote:
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande m'affiche progressivement les print i. Mais la "gauge" elle ne se met à jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100 instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres l'incrementation semblerait faire l'affaire.
Sous linux ça ne suffit pas...
Ensuite il faut voir si on veut vraiment la redessiner apres chaque calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement la possibilite de mettre en place un alarme pour executer une fonction regulierement.
oui, bien entendu ;-) Le code que j'ai posté est le code minimal que j'ai écrit pour démontrer le fonctionnement qui me semble anormal...
tiissa@free.fr wrote:
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande
m'affiche progressivement les print i. Mais la "gauge" elle ne se met à
jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100
instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas
lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme
de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres
l'incrementation semblerait faire l'affaire.
Sous linux ça ne suffit pas...
Ensuite il faut voir si on veut vraiment la redessiner apres chaque
calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement
la possibilite de mettre en place un alarme pour executer une fonction
regulierement.
oui, bien entendu ;-) Le code que j'ai posté est le code minimal que
j'ai écrit pour démontrer le fonctionnement qui me semble anormal...
Lorsque je l'exécute (un clique sur le bouton ok), la ligne de commande m'affiche progressivement les print i. Mais la "gauge" elle ne se met à jour qu'à la fin de la boucle sur i... Elle passe de 0 à 100 instantanément. Qu'est-ce que je fais mal ? Je ne dois quand même pas lancer un thread pour faire ça ?
Je ne connais pas wxPython mais, en general, lorsque c'est un probleme de mise-a-jour, une solution est de lui demander de redessiner.
Apres un petit tour sur la doc, self.gauge.Refresh() apres l'incrementation semblerait faire l'affaire.
Sous linux ça ne suffit pas...
Ensuite il faut voir si on veut vraiment la redessiner apres chaque calcul ou seulement a une frequence fixee. Dans ce cas, il y a surement la possibilite de mettre en place un alarme pour executer une fonction regulierement.
oui, bien entendu ;-) Le code que j'ai posté est le code minimal que j'ai écrit pour démontrer le fonctionnement qui me semble anormal...
fraca7
fraca7 wrote:
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification de la valeur d'un widget génère un événement pour qu'il actualise son affichage. Apparement ça ne le fait pas.
Certes, les évènements sont 'générés', ie les messages sont postés dans la queue de message du thread principal, mais si celui-ci ne retourne pas dans la boucle d'évènement pour les gérer, ils n'ont aucun effet. En théorie.
Par contre, le code que j'ai posté fonctionne sous windows :-(
Effectivement. C'est louche. La méthode SetValue doit 'forcer' le traitement des messages dans wxMSW mais pas dans wxGTK... Il faudrait jeter un coup d'oeil au source pour être sûr...
Enfin, de toutes façons je pense que c'est toujours une mauvaise idée de faire un traitement de longue haleine dans le thread principal d'un GUI.
fraca7 wrote:
Pendant qu'on est là-dedans, on ne passe pas par la boucle
d'évènements de wx, alors il ne risque pas de se passer quoi que ce
soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour
incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification
de la valeur d'un widget génère un événement pour qu'il actualise son
affichage. Apparement ça ne le fait pas.
Certes, les évènements sont 'générés', ie les messages sont postés dans
la queue de message du thread principal, mais si celui-ci ne retourne
pas dans la boucle d'évènement pour les gérer, ils n'ont aucun effet. En
théorie.
Par contre, le code que j'ai posté fonctionne sous windows :-(
Effectivement. C'est louche. La méthode SetValue doit 'forcer' le
traitement des messages dans wxMSW mais pas dans wxGTK... Il faudrait
jeter un coup d'oeil au source pour être sûr...
Enfin, de toutes façons je pense que c'est toujours une mauvaise idée de
faire un traitement de longue haleine dans le thread principal d'un GUI.
Pendant qu'on est là-dedans, on ne passe pas par la boucle d'évènements de wx, alors il ne risque pas de se passer quoi que ce soit...
Il faut soit faire ça dans un thread soit utiliser un wx.Timer pour incrémenter la valeur à intervalles réguliers.
Ca me semblait normal, dans un environnement objet, que la modification de la valeur d'un widget génère un événement pour qu'il actualise son affichage. Apparement ça ne le fait pas.
Certes, les évènements sont 'générés', ie les messages sont postés dans la queue de message du thread principal, mais si celui-ci ne retourne pas dans la boucle d'évènement pour les gérer, ils n'ont aucun effet. En théorie.
Par contre, le code que j'ai posté fonctionne sous windows :-(
Effectivement. C'est louche. La méthode SetValue doit 'forcer' le traitement des messages dans wxMSW mais pas dans wxGTK... Il faudrait jeter un coup d'oeil au source pour être sûr...
Enfin, de toutes façons je pense que c'est toujours une mauvaise idée de faire un traitement de longue haleine dans le thread principal d'un GUI.