Question

Sometimes my QProgressDialog shows, sometimes it doesn't ever show at all (as if processEvents weren't called). Are there any artifacts of the processEvents() command that may cause the QProgressDialog not to show under certain circumstances?

My question is general because I have not yet been able to isolate the problem in my code. However, I have noticed that when my QProgressDialog does not show it occurs when I am accessing a text file using a config parser. The work around was to do a time.sleep() after the file has been closed (perhaps to ensure the process completed and that processEvents would then commence showing the QProgressDialog).

If it helps, here's my code for running the QProgressDialog as a generator:

def progress_dialog(self, data, label, window_title, stop_label, capture_bar=False):
    bar = QProgressDialog(label, stop_label, 0, len(data))
    if capture_bar: self.prog_bar = bar
    bar.setWindowTitle(window_title)
    for k, d in enumerate(data):
        QCoreApplication.instance().processEvents()
        if bar.wasCanceled():
            raise GeneratorExit
        # set the next value beyond the start of 0
        bar.setValue(k+1)
        # again process events to draw the new label and value
        QCoreApplication.instance().processEvents()
        yield(d)
        raise StopIteration

Again, sorry I don't have a full code snippet of the isolated problem (and the full code is too big of an ocean). I guess what I'm looking for is a why of checking if the processEvents() command is doing its job (because clearly I am calling it but it hangs on other processes rather than showing the dialog).

Edit:

According to this support request doing a "bar.show()" command will force the progress bar to show.

http://redmine.smar.fi/issues/265

I'm going to wait a few weeks and make sure this is a guaranteed fix before posting it as an answer.

Was it helpful?

Solution 2

According to this support request doing a bar.show() command will force the progress bar to show: http://redmine.smar.fi/issues/265

Simply call the show() method before every process events call and after the progress bar is first constructed.

I've waited nearly 4 months and this solution has worked without failing yet. Seems to be a sufficient answer.

OTHER TIPS

If you need to show a QProgessDialog regardless of the duration of the process, use its setMinimumDuration method with a value of 0. According to the documentation the default minimum is 4000ms.

This might be an old thread, but I had a similar problem and show() made the dialog appear, but empty. So, I came up with this decorator that I apply to functions that I want to run blocking, while permitting GUI thread to process events.

def nongui(fun):
    """Decorator running the function in non-gui thread while
    processing the gui events."""
    from multiprocessing.pool import ThreadPool
    from PyQt4.QtGui import QApplication

    def wrap(*args, **kwargs):
        pool = ThreadPool(processes=1)
        async = pool.apply_async(fun, args, kwargs)
        while not async.ready():
            async.wait(0.01)
            QApplication.processEvents()
        return async.get()

    return wrap

Then, it's easy to write your calculating function normally with the decorator:

@nongui
def work(input):
    # Here you calculate the output and set the 
    # progress dialog value
    return out

and then run it as usual:

out = work(input)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top