wx.WrapSizer.IsSpaceItem fails

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

wx.WrapSizer.IsSpaceItem fails

wxPython-users mailing list-2
Has anyone actually tried out wx.WrapSizer.IsSpaceItem? It is now overridable in Phoenix, but it just doesn't work for me...

class MyWrapSizer(wx.WrapSizer):
   
def IsSpaceItem(self, item):
        window
= item.GetWindow()
       
if isinstance(window, wx.StaticText):
           
return True  # if sizer item has a static text inside, then pretend it's a space
       
return wx.WrapSizer.IsSpaceItem(self, item)

class MainFrame(wx.Frame):
   
def __init__(self, *a, **k):
        wx
.Frame.__init__(self, *a, **k)
        p
= wx.Panel(self)
        sizer
= MyWrapSizer(wx.HORIZONTAL, wx.REMOVE_LEADING_SPACES)
       
for _ in range(5):
            sizer
.Add(wx.Button(p, size=(50, 50)))
        sizer
.Add(wx.StaticText(p, -1, 'Hello!')) # now this one should be treated as space
       
for _ in range(5):
            sizer
.Add(wx.Button(p, size=(50, 50)))
        p
.SetSizer(sizer)

This should be a reasonable thing to ask - yet if fails with

wx._core.wxAssertionError: C++ assertion "!sizer || m_containingSizer != sizer" failed at ..\..\src\common\wincmn.cpp(2470) in wxWindowBase::SetContainingSizer(): Adding a window to the same sizer twice?

The above exception was the direct cause of the following exception:

SystemError: <class 'wx._core.SizerItem'> returned a result with an error set

Please note that re-creating the original behaviour works fine:

class MyWrapSizer(wx.WrapSizer):
   
def IsSpaceItem(self, item):
       
return item.IsSpacer() # this works like a charm

However, testing for SizerItem.IsSizer (instead of IsSpacer) behaves erratically depending of the actual content of the (sub)sizer:

class MyWrapSizer(wx.WrapSizer):
   
def IsSpaceItem(self, item):
       
return item.IsSizer()

class MainFrame(wx.Frame):
   
def __init__(self, *a, **k):
        wx
.Frame.__init__(self, *a, **k)
        p
= wx.Panel(self)
        sizer
= MyWrapSizer(wx.HORIZONTAL, wx.REMOVE_LEADING_SPACES)
       
for _ in range(5):
            sizer
.Add(wx.Button(p, size=(50, 50)))
        s
= wx.BoxSizer()
        s
.Add(wx.TextCtrl(p, -1, 'Hello!'))  
        sizer
.Add(s) # this should be a space, now
       
for _ in range(5):
            sizer
.Add(wx.Button(p, size=(50, 50)))
        p
.SetSizer(sizer)

This doesn't fail, but it doesn't quite work either. If you put a StaticText inside the sub-sizer instead, it looks better, but still can't wrap it nicely.

My guess is, even if wx.WrapSizer.IsSpaceItem is indeed overridable, the behind-the-scenes machinery of wx.Sizer.Add is just too much for wxPython to tamper with.
Or - it's just me missing something obvious here?

riccardo

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wx.WrapSizer.IsSpaceItem fails

Robin Dunn
'ricpol' via wxPython-users wrote:
> My guess is, even if wx.WrapSizer.IsSpaceItem is indeed overridable,
> the behind-the-scenes machinery of wx.Sizer.Add is just too much for
> wxPython to tamper with.

More or less.  The base RecalcSizes calls window.SetContainingSizer if
the item is a window, but that code path is avoided if IsSpaceItem
returns True, and since the containing sizer is already set on that item
then the assertion error is triggered. You can avoid that by calling
window.SetContainingSize(None) yourself.

However even with that addition I don't think you can do what you are
trying to do with this code.  The static text widget will still be
visible, it just won't be used for calculating the positions and sizes
of the other items, doing that with spacer items is okay since they
don't draw anything.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wx.WrapSizer.IsSpaceItem fails

wxPython-users mailing list-2
Thanks for clarifying.
I've given SetContainingSizer a run... Well it tries very hard to keep the house clean, but still fails in various ways depending on the actual managed widget, plus it almost always crashes on exit.

> I don't think you can do what you are trying to do with this code

I was just looking for possible use cases for wx.WrapSizer.IsSpaceItem but it seems this function is just too hard to set up to be useful. Yes, maybe you could work your black magic overriding RecalcSizes too, but the game isn't worth the candle here.
I can't find any example in wxWidgets too... my hunch is that it's just a not-so-carefully-designed api, that was added to the mix because who knows, someone might find a use for it one day.


r




Il giorno mercoledì 12 luglio 2017 21:34:29 UTC+2, Robin Dunn ha scritto:
'ricpol' via wxPython-users wrote:
> My guess is, even if wx.WrapSizer.IsSpaceItem is indeed overridable,
> the behind-the-scenes machinery of wx.Sizer.Add is just too much for
> wxPython to tamper with.

More or less.  The base RecalcSizes calls window.SetContainingSizer if
the item is a window, but that code path is avoided if IsSpaceItem
returns True, and since the containing sizer is already set on that item
then the assertion error is triggered. You can avoid that by calling
window.SetContainingSize(None) yourself.

However even with that addition I don't think you can do what you are
trying to do with this code.  The static text widget will still be
visible, it just won't be used for calculating the positions and sizes
of the other items, doing that with spacer items is okay since they
don't draw anything.

--
Robin Dunn
Software Craftsman
<a href="http://wxPython.org" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2FwxPython.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHG9kM-NEpJfIvl_lWJvA23SuLjOA&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2FwxPython.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHG9kM-NEpJfIvl_lWJvA23SuLjOA&#39;;return true;">http://wxPython.org

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wx.WrapSizer.IsSpaceItem fails

Robin Dunn
'ricpol' via wxPython-users wrote:
> I can't find any example in wxWidgets too... my hunch is that it's
> just a not-so-carefully-designed api, that was added to the mix
> because who knows, someone might find a use for it one day.
>

Probably.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Loading...