Niek de Klein
Niek de Klein

Reputation: 8824

How to thread wxPython progress bar

I'm trying to thread wx.ProgressDialog. I got a Progress threading class

class Progress(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        max = 1000000

        dlg = wx.ProgressDialog("Progress dialog example",
                               "An informative message",
                               maximum = max,
                               parent=None,
                               style = wx.PD_CAN_ABORT
                                | wx.PD_APP_MODAL
                                | wx.PD_ELAPSED_TIME
                                | wx.PD_ESTIMATED_TIME
                                | wx.PD_REMAINING_TIME
                                )
        keepGoing = True
        count = 0

        while keepGoing and count < max:
            count += 1
            wx.MilliSleep(250)

            if count >= max / 2:
                (keepGoing, skip) = dlg.Update(count, "Half-time!")
            else:
                (keepGoing, skip) = dlg.Update(count)
        dlg.Destroy()

which gets called when I push a button by

class MiPPanel ( wx.Panel ):
    [...]
    def runmiP(self, event):
        thread1 = Progress() 
        thread1.start() 

When I run thread1.start() I get 100s of warnings of the type 2012-12-01 00:31:19.215 Python[3235:8807] *** __NSAutoreleaseNoPool(): Object 0x11a88f300 of class NSConcreteAttributedString autoreleased with no pool in place - just leaking and the progress bar doesn't show up.

How can I use threading with wxPython to make a progress bar?

Upvotes: 1

Views: 2342

Answers (2)

Demolishun
Demolishun

Reputation: 1650

All wxPython widgets and manipulation should be in a single thread. If you want to have a dialog controlled by another thread then you will have to use timers and queues to message the dialog from the other thread.

Another way I understand is supposed to work (I have not tested this) it to create a completely separate wxApp in another thread just for your dialog. You will have to communicate somehow back to the main thread still.

Edit: Here is a link to more information. It has some info at the bottom about using wx.CallAfter to update progress of a worker thread. It also shows how to run a single function in a separate thread without creating a separate class.

wxPython Threading

Upvotes: 1

abarnert
abarnert

Reputation: 365667

It looks like it's complaining about argument 4 not being a wxWindow (hence the argument 4 of type 'wxWindow *' part of the error).

Looking at your call, argument 4 is passing parent=self. So, what is self? In other words, what class is the method with this code a part of? Is it something that's a wx.Window or subclass of one, or is it something like an Application or a Progress that isn't?

(Actually, given that you're passing parent as a keyword argument, it's just a coincidence that it happened to be in the 4th position in your call to the wx.ProgressDialog constructor and also be in the 4th position to the call to the underlying C++ function, which is what's actually complaining. You'd get the same error if you switched maximum and parent, and I think it would still say argument 4 instead of argument 3.)

To verify this, try taking out the parent=self in the call that fails, and it should work, or adding parent=object() to the call with just None that works, and it should fail.

Of course that doesn't actually fix the problem. But to do that, you have to figure out what you wanted the parent to be and pass that instead of self.

PS, I don't think the problem has anything to do with your threading at all.

Upvotes: 0

Related Questions