wx python 3.0.2 经典SetFocus一击
wx python 3.0.2 classic SetFocus blows
我有一个 Progress class 在 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里面没有wx)
然而在 3.02 中打击:
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
现在有人能看出这个 window 有什么不对吗?如所见,Progress 实例化于:
with balt.Progress(_(u'Refreshing Installers...'),u'\n'+u' '*60, abort=canCancel) as progress:
所以 parent 是 None - 是因为那个吗?但是,为什么 3.0.2 中的行为发生了变化? 编辑: 好吧 - 传递一个非 None parent 没有区别
顺便说一句,如果我删除了 SetFocus 调用,它会在稍后继续调用另一个 setFocus 调用:
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()
不确定是否需要所有这些花招或是否可以简化,但我最关心的是为什么 window 无效。
在 Windows 上,ProgressDialog
现在是常用控件(如 MessageDialog
、FileDialog
等),而不是像它一样在 wx 中实现的通用对话框以前是。所以它不再是真正的原生 window,而只是平台 API 的包装器。所以这意味着它没有本机 window 句柄,并且大多数非 ProgressDialog
-specific APIs 像 SetFocus
将不起作用。
我有一个 Progress class 在 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里面没有wx)
然而在 3.02 中打击:
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
现在有人能看出这个 window 有什么不对吗?如所见,Progress 实例化于:
with balt.Progress(_(u'Refreshing Installers...'),u'\n'+u' '*60, abort=canCancel) as progress:
所以 parent 是 None - 是因为那个吗?但是,为什么 3.0.2 中的行为发生了变化? 编辑: 好吧 - 传递一个非 None parent 没有区别
顺便说一句,如果我删除了 SetFocus 调用,它会在稍后继续调用另一个 setFocus 调用:
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()
不确定是否需要所有这些花招或是否可以简化,但我最关心的是为什么 window 无效。
在 Windows 上,ProgressDialog
现在是常用控件(如 MessageDialog
、FileDialog
等),而不是像它一样在 wx 中实现的通用对话框以前是。所以它不再是真正的原生 window,而只是平台 API 的包装器。所以这意味着它没有本机 window 句柄,并且大多数非 ProgressDialog
-specific APIs 像 SetFocus
将不起作用。