wx python 3.0.2 classic SetFocus blows

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

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.

回答1:

On Windows the ProgressDialog is now a stock common control (like MessageDialog, FileDialog, etc.) instead of a generic dialog implemented in wx like it used to be. So it is not a real native window any longer but just a wrapper around a platform API. So this means that it has no native window handle, and most non-ProgressDialog-specific APIs like SetFocus will not work.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!