BrtH
BrtH

Reputation: 2664

Sending progress from thread to gui

I have a qt program with a statusbar. I am looking for a good way to update this statusbar. I could of course emit signals from the code, but I want to keep the gui and the 'real' code separated, and I want the code to be able to run independantly from the gui. The solution that I came up with, is to yield the subtotal to the gui, as is shown below in an extremely simplified example.

#in file1:
from time import sleep

class WorkerClass():
    def updater(self):
        yield 10  # total
        if some_condition:
            yield 'end'  # return early
        for i in xrange(1, 11):
            sleep(1)  # dummy for real task
            yield i  # subtotal


#in file2, in some function in the MainWindow class:
worker = WorkerClass()
u = worker.updater()
total = u.next()
self.progress_bar.setRange(0, total)
for i in u:
    if i == 'end': break
    self.progress_bar.setValue(i)
print 'done!'

I feel however that this is not the way it should be done. What is a better way to return the subtotal, without using qt code in file1?

Upvotes: 3

Views: 129

Answers (1)

shx2
shx2

Reputation: 64298

Set up the progress bar as a (custom) observer. For example:

def dowork(observer=None):
  worker = WorkerClass()
  u = worker.updater()
  total = u.next()
  if observer:
    observer.progress_total(total)
  for i in u:
    if i == 'end': break
    if observer:
      observer.progress(i)
  print 'done!'

The observer can look something like:

class ProgressBarObserver(object):
  def __init__(self, progbar):
    self.progbar = progbar
  def progress_total(self, n):
    self.progbar.setRange(0, n)
  def progress(self, i):
    self.progbar.setValue(i)

And the calling code pairs them up:

dowork(ProgressBarObserver(self.progress_bar))

I hope that helps.

Upvotes: 2

Related Questions