2017-06-19 14 views
0

Je n'arrive pas à mettre à jour wx.Gauage en temps réel. Le wx.Gauge est instancié dans une classe appelée ProgressWindow. ProgressWindow est utilisé pour fournir une barre de progression lorsque le travail est en cours. La mise à jour de la jauge se fait sur un fil séparé afin de ne pas bloquer le travail en cours. Malheureusement, lorsque j'instancie et démarre la fenêtre de progression, la jauge n'est mise à jour qu'à la fin de la fonction de test "fn_testing_progress_window". Quelqu'un peut-il voir pourquoi cela se passe? J'essaye d'avoir la jauge être mise à jour quand "fn_increment_count" est appelé.wx.Gauge ne se mettant pas à jour en temps réel

Remarque: La raison pour laquelle j'ai une file d'attente pour gérer la demande de mise à jour de la jauge est que si le travail en cours est réparti sur plusieurs threads, chaque thread peut mettre à jour la jauge.

def fn_testing_progress_window(): 
    pw = ProgressWindow(self.main_panel) 
    pw.fn_start() 

    pw.fn_increment_count(increment = 50, msg = "50 Now") 
    time.sleep(3) 
    pw.fn_increment_count(increment = 75, msg = "75 Now") 
    time.sleep(3) 
    pw.fn_increment_count(increment = 100, msg = "Finished") 


def fn_start(self): 
    print "Starting Progress" 
    _runner_thread = threading.Thread(target = self.fn_run) 
    _runner_thread.start() 

def fn_run(self): 
    self._running = True 
    self._current_count = 0 

    while(self._running): 
     # Wait til there is something in queue or til run is stopped 
     while True: 
      if (not self._update_queue.empty()): 
       print "not empty" 
       break 

      if (not self._running): 
       break 

     _value, _msg = self._update_queue.get() 

     # Update progress bar accordingly 
     if _value: 
      self._current_count += _value 
      print "Updating value: %d" %(self._current_count) 
      wx.CallAfter(self._progress_gauge.SetValue, self._current_count) 

     if _msg: 
      print "Updating msg: %s" %(_msg) 
      wx.CallAfter(self._progress_output.SetValue, str(_msg)) 

     if (self._current_count >= self._total_count): 
      pass 

     # Have time for msg to appear 
     time.sleep(0.1) 


def fn_increment_count(self, 
         increment = 1, 
         msg = None): 
    """ 
    Ability to update current count on progress bar and progress msg. 
    If nothing provided increments current count by 1 
    """ 
    _item_l = (increment, msg) 
    self._update_queue.put(_item_l) 

Répondre

3

Vous ne pouvez pas mettre à jour un wxGauge, ou tout autre contrôle de l'interface graphique, d'un thread séparé. Les mises à jour de l'interface graphique ne doivent être effectuées qu'à partir du thread principal de l'interface graphique, afin que votre thread principal ne bloque pas (comme vous le faites): non seulement cela empêche les mises à jour, mais cela empêche également tout votre programme. Au lieu de cela, faites le inverse: effectuez votre long travail dans un autre thread et n'enregistrez que des événements dans le thread principal à chaque fois qu'il a besoin de mettre à jour quelque chose dans l'interface graphique. Le thread principal n'a alors pas besoin de faire quoi que ce soit de spécial, si ce n'est de définir des gestionnaires pour ces événements qui mettraient à jour l'indicateur de progression.

+0

Merci. Cela a résolu tous mes problèmes. J'ai fait la fonction en faisant tout le travail sur un thread séparé poster des événements à l'interface graphique. Cela a également résolu un autre problème que j'avais qui obtenait "No Response" pour une tâche de longue durée. – Sam