2017-06-19 35 views
0

我無法實時更新wx.Gauage。 wx.Gauge在一個名爲ProgressWindow的類中實例化。 ProgressWindow用於在工作完成時提供進度條。 正在一個單獨的線程上完成更新量表,以便它不會阻止正在完成的工作。不幸的是,當我實例化並啓動進度窗口時,量表只會在「fn_testing_progress_window」測試函數的最後更新。任何人都可以看到爲什麼會發生?我試圖在調用「fn_increment_count」時更新量表。wx.Gauge不實時更新

注意:我有一個隊列來處理更新量表的請求的原因是,如果正在完成的工作分散在多個線程中,則每個線程都可以更新量表。

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) 

回答

3

您無法從單獨的線程更新wxGauge或任何其他GUI控件。 GUI更新只能從主GUI線程完成,因此您的主線程不能阻塞(如您所做的那樣):這不僅會阻止更新發生,還會導致整個程序無響應。

相反,反過來:在另一個線程中執行長時間的工作,只要需要更新GUI中的某些內容,就將事件發佈到主線程。除了定義用於更新進度指示器的事件的處理程序之外,主線程不需要做任何特殊的事情。

+0

謝謝。這解決了我所有的問題。我讓這個函數在一個單獨的線程上完成所有工作,將事件發佈到GUI。這也解決了我遇到的另一個問題,那就是長時間運行的任務會得到「無響應」。 – Sam