I had a Progress class that was working fine in 2.8.12.1 unicode:
class Progress(bolt.Progress): """Progress as progress dialog.""" def __init__(self,title=_(u'Progress'),message=u' '*60,parent=None, style=wx.PD_APP_MODAL|wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_SMOOTH, abort=False, onAbort=None): if abort: style |= wx.PD_CAN_ABORT self.fnAbort = onAbort self.dialog = wx.ProgressDialog(title,message,100,parent,style) self.dialog.SetFocus() #### line 1295 in the traceback is here #### bolt.Progress.__init__(self) self.message = message self.isDestroyed = False self.prevMessage = u'' self.prevState = -1 self.prevTime = 0 (bolt.Progress has no wx in it)
In 3.02 however blows with:
Traceback (most recent call last): ... File "bash\basher\__init__.py", line 2670, in _refresh_installers_if_needed with balt.Progress(_(u'Refreshing Installers...'),u'\n'+u' '*60, abort=canCancel) as progress: File "bash\balt.py", line 1295, in __init__ self.dialog.SetFocus() File "C:\_\Python27\lib\site-packages\wx-3.0-msw\wx\_core.py", line 10129, in SetFocus return _core_.Window_SetFocus(*args, **kwargs) wx._core.PyAssertionError: C++ assertion "hWnd" failed at ..\..\src\msw\window.cpp(562) in wxWindow::SetFocus(): can't set focus to invalid window Now can anyone spot what is invalid about this window ? As seen the Progress is instantiated in:
with balt.Progress(_(u'Refreshing Installers...'),u'\n'+u' '*60, abort=canCancel) as progress: so parent is None - is it because of that ? However why the change in behavior in 3.0.2 ? EDIT: well no - passing a non None parent in makes no difference
Incidentally if I remove the SetFocus call it goes on to blow in another setFocus call later on:
def doProgress(self,state,message): if not self.dialog: raise StateError(u'Dialog already destroyed.') elif (state == 0 or state == 1 or (message != self.prevMessage) or (state - self.prevState) > 0.05 or (time.time() - self.prevTime) > 0.5): self.dialog.SetFocus() #### blows here, this self.dialog is really, really invalid #### if message != self.prevMessage: ret = self.dialog.Update(int(state*100),message) if not ret[0]: if self.onAbort(): raise CancelError else: ret = self.dialog.Update(int(state*100)) if not ret[0]: if self.onAbort(): raise CancelError self.prevMessage = message self.prevState = state self.prevTime = time.time() Not sure if all this hocus pocus is needed or if it could be simplified, but my immediate concern is why the window is invalid.