I came across a strange behaviour while looking at the multi-line text capabilities of UltimateListCtrl, and basically the way DoGetBestSize is handled. Cutting the story short, in ULC I create the list control header explicitly passing a non-default “size” parameter to the header window (which is a subclass of wx.PyControl).
Using wxPython 2.8.11.0 on Windows Vista/7, the DoGetBestSize method for the header control is correctly called and the header window is correctly sized. Using 2.9.2.4, the DoGetBestSize method is never called, so the window gets messed up. The only way I found out to actually get that method executed is to remove the “size” parameter (or to give a wx.DefaultSize value to it) while constructing the header window.
The attached sample reproduces the problem for me. If you run it with 2.8, youll see the wx.TextCtrl populated with messages sent by the wx.PyControl. If you use 2.9, no message will appear.
I believe it to be a bug in 2.9, as passing a non-default “size” argument to a wx.PyControl does not necessarily mean “forget about calculating the best size for this control”. Its just a guess or a default value for some situations.
It looks like at least part of the difference is that in 2.9 the minsize is being set to the size passed in to the constructor like it does for other control classes. In 2.8 it doesn't do that for wx.Control, just for the actual widget controls. If both components of the minsize are set to non-devault values then GetBestSize will not be called from GetEffectiveMinSize, which is the method used by sizers.
wxSize wxWindowBase::GetEffectiveMinSize() const
{
// merge the best size with the min size, giving priority to the min size
wxSize min = GetMinSize();
if (min.x == wxDefaultCoord || min.y == wxDefaultCoord)
{
wxSize best = GetBestSize();
if (min.x == wxDefaultCoord) min.x = best.x;
if (min.y == wxDefaultCoord) min.y = best.y;
}
return min;
}
···
On 10/31/11 3:43 AM, Andrea Gavana wrote:
Hi All,
I came across a strange behaviour while looking at the multi-line
text capabilities of UltimateListCtrl, and basically the way
DoGetBestSize is handled. Cutting the story short, in ULC I create the
list control header explicitly passing a non-default "size" parameter to
the header window (which is a subclass of wx.PyControl).
Using wxPython 2.8.11.0 on Windows Vista/7, the DoGetBestSize method for
the header control is correctly called and the header window is
correctly sized. Using 2.9.2.4, the DoGetBestSize method is *never*
called, so the window gets messed up. The only way I found out to
actually get that method executed is to remove the "size" parameter (or
to give a wx.DefaultSize value to it) while constructing the header window.
The attached sample reproduces the problem for me. If you run it with
2.8, youll see the wx.TextCtrl populated with messages sent by the
wx.PyControl. If you use 2.9, no message will appear.
I believe it to be a bug in 2.9, as passing a non-default "size"
argument to a wx.PyControl does not necessarily mean "forget about
calculating the best size for this control". Its just a guess or a
default value for some situations.
I came across a strange behaviour while looking at the multi-line
text capabilities of UltimateListCtrl, and basically the way
DoGetBestSize is handled. Cutting the story short, in ULC I create the
list control header explicitly passing a non-default “size” parameter to
the header window (which is a subclass of wx.PyControl).
Using wxPython 2.8.11.0 on Windows Vista/7, the DoGetBestSize method for
the header control is correctly called and the header window is
correctly sized. Using 2.9.2.4, the DoGetBestSize method is never
called, so the window gets messed up. The only way I found out to
actually get that method executed is to remove the “size” parameter (or
to give a wx.DefaultSize value to it) while constructing the header window.
The attached sample reproduces the problem for me. If you run it with
2.8, youll see the wx.TextCtrl populated with messages sent by the
wx.PyControl. If you use 2.9, no message will appear.
I believe it to be a bug in 2.9, as passing a non-default “size”
argument to a wx.PyControl does not necessarily mean "forget about
calculating the best size for this control". Its just a guess or a
default value for some situations.
It looks like at least part of the difference is that in 2.9 the minsize is being set to the size passed in to the constructor like it does for other control classes. In 2.8 it doesn’t do that for wx.Control, just for the actual widget controls. If both components of the minsize are set to non-devault values then GetBestSize will not be called from GetEffectiveMinSize, which is the method used by sizers.
wxSize wxWindowBase::GetEffectiveMinSize() const
{
// merge the best size with the min size, giving priority to the min size
wxSize min = GetMinSize();
if (min.x == wxDefaultCoord || min.y == wxDefaultCoord)
{
wxSize best = GetBestSize();
if (min.x == wxDefaultCoord) min.x = best.x;
if (min.y == wxDefaultCoord) min.y = best.y;
}
return min;
}
Thank you for that, I guess then the obvious thing to do is not to pass any size parameter for custom controls (if I want to get DoGetBestSize executed, I mean). I’ll see if I can get any other strange behaviour for the other AGW widgets.
On a completely unrelated note, I am still getting assertion errors from the AUI (wx.lib.agw one) demo, as per attached screenshot. How do I debug these? How can I find where the offending line is? It’s curious as other apps I have work OK with the latest AGW from SVN, but the demo asserts when I close the main frame…
On a completely unrelated note, I am still getting assertion errors from
the AUI (wx.lib.agw one) demo, as per attached screenshot. How do I
debug these? How can I find where the offending line is? It's curious as
other apps I have work OK with the latest AGW from SVN, but the demo
asserts when I close the main frame...
Running this in the WIT with the demo's AuiFrame selected:
>>> for c in [obj] + list(obj.Children):
... if c is not c.GetEventHandler():
... print c.__class__.__name__, ' has handler ', c.GetEventHandler().__class__.__name__
...
gives me this:
AuiFrame has handler AuiManager
AuiNotebook has handler AuiManager
Grid has handler EvtHandler
HtmlWindow has handler EvtHandler
AuiNotebook has handler AuiManager
AuiFloatingFrame has handler AuiManager
We can ignore the Grid and HtmlWindow items since they can be expected to clean up after themselves. Are any of the remaining windows calling AuiManager.UnInit so the manager will remove itself from the managed frame's EventHandler stack? Perhaps we should find a way to do that automatically...
On a completely unrelated note, I am still getting assertion errors from
the AUI (wx.lib.agw one) demo, as per attached screenshot. How do I
debug these? How can I find where the offending line is? It’s curious as
other apps I have work OK with the latest AGW from SVN, but the demo
asserts when I close the main frame…
Running this in the WIT with the demo’s AuiFrame selected:
for c in [obj] + list(obj.Children):
… if c is not c.GetEventHandler():
… print c.class.name, ’ has handler ', c.GetEventHandler().class.name
…
gives me this:
AuiFrame has handler AuiManager
AuiNotebook has handler AuiManager
Grid has handler EvtHandler
HtmlWindow has handler EvtHandler
AuiNotebook has handler AuiManager
AuiFloatingFrame has handler AuiManager
We can ignore the Grid and HtmlWindow items since they can be expected to clean up after themselves. Are any of the remaining windows calling AuiManager.UnInit so the manager will remove itself from the managed frame’s EventHandler stack? Perhaps we should find a way to do that automatically…
Thanks. I think I have fixed it in the latest SVN revision.
Andrea.
“Imagination Is The Only Weapon In The War Against Reality.”