简体   繁体   中英

wx.Gauge not updating in real-time

I'm having trouble updating wx.Gauage in real time. The wx.Gauge is instantiated in a class called ProgressWindow. ProgressWindow is used to provide a progress bar when work is being done. Updating the gauge is being done on a separate thread so that it does not block the work being done. Unfortunately when I instantiate and start the progress window, the gauge only get's updated at the very end of the "fn_testing_progress_window" test function. Can anyone see why this is happening? I'm trying to have the gauge be updated when "fn_increment_count" is called.

Note: The reason why I have a queue to handle request to update the gauge is if the work being done is spread across multiple threads, each thread can update the 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)

You can't update a wxGauge , or any other GUI control, from a separate thread. GUI updates should be only done from the main, GUI thread, so your main thread must not block (as you do): not only this prevents updates from happening, but it also makes your entire program unresponsive.

Instead, do it the other way round: perform your long work in another thread and just post events to the main thread from it whenever it needs to update something in the GUI. The main thread then doesn't need to do anything special, other than defining handlers for these events which would update the progress indicator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM