Greedy ComboBoxes

Hello,

I am noticing that my ComboBoxes are being a little greedy with their MinSize, as per the attached screenshot. I have noticed that controls seem to have a "minimum minimum size". Of course I can set their Sizes manually but then I am not accommodating for all the possible scenarios that would change the text size (themes/fonts/dpi/etc).

Is there either a way to make them actually size in a more compact manner, or manually do the calculation by getting the width of the text and then the width of the drop-down button?

Thanks!
- Mike

sscombos.png

I tried to do the same thing, and the text width is easily calculated with

def CalcStaticWidth(ParentWindow, text):
“”"The function calculates the width of the wx.StaticText

containing completely «text», with the standard font of ParentWindow"""
st = wx.StaticText(ParentWindow, wx.ID_ANY, text)
width = st.Size.width
st.Close(True)
st.Destroy()

return width

But I could not solve the problem of calculating the width of the drop-down button, that probably changes with the OS.

···

2008/8/6 Mike Rooney mxr@qvii.com

Hello,

I am noticing that my ComboBoxes are being a little greedy with their MinSize, as per the attached screenshot. I have noticed that controls seem to have a “minimum minimum size”. Of course I can set their Sizes manually but then I am not accommodating for all the possible scenarios that would change the text size (themes/fonts/dpi/etc).

Is there either a way to make them actually size in a more compact manner, or manually do the calculation by getting the width of the text and then the width of the drop-down button?

Thanks!

  • Mike

wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Hello,

I tried to do the same thing, and the text width is easily calculated with

def CalcStaticWidth(ParentWindow, text):
“”"The function calculates the width of the wx.StaticText

containing completely «text», with the standard font of ParentWindow"""
st = wx.StaticText(ParentWindow, wx.ID_ANY, text)
width = st.Size.width
st.Close(True)
st.Destroy()

return width

FYI: You can do this in a much easier way by using GetTextExtent.

txt_w, txt_h = ParentWindow.GetTextExtent(text)

···

On 8/6/08, raffaello barbarossa.platz@gmail.com wrote:

But I could not solve the problem of calculating the width of the drop-down button, that probably changes with the OS.

2008/8/6 Mike Rooney mxr@qvii.com

Hello,

I am noticing that my ComboBoxes are being a little greedy with their MinSize, as per the attached screenshot. I have noticed that controls seem to have a “minimum minimum size”. Of course I can set their Sizes manually but then I am not accommodating for all the possible scenarios that would change the text size (themes/fonts/dpi/etc).

Is there either a way to make them actually size in a more compact manner, or manually do the calculation by getting the width of the text and then the width of the drop-down button?

Thanks!

  • Mike

wxpython-users mailing list
wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users


wxpython-users mailing list
wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Cody Precord wrote:

Hello,

    I tried to do the same thing, and the text width is easily
    calculated with

    def CalcStaticWidth(ParentWindow, text):
        """The function calculates the width of the wx.StaticText
        containing completely «text», with the standard font of
    ParentWindow"""
        st = wx.StaticText(ParentWindow, wx.ID_ANY, text)
        width = st.Size.width
        st.Close(True)
        st.Destroy()
        return width

FYI: You can do this in a much easier way by using GetTextExtent.
txt_w, txt_h = ParentWindow.GetTextExtent(text)

This isn't a terrible solution, as I could use that and then add a liberal amount of pixels to account for the drop-down button and it would probably be better. Although it seems like there should be a way to make the control size itself appropriately.

- Mike

···

On 8/6/08, *raffaello* <barbarossa.platz@gmail.com > <mailto:barbarossa.platz@gmail.com>> wrote:

Thanks to Cody Precord for the information.
To Mike: how much liberal should that amount of pixels be? Because I am afraid this is the behaviour of the OS with the combo, only it stays carefully on the safe side.

In order to draw the drop-down button, it has to assign a size to it. Possible that nobody knows how to extract that value?

···

2008/8/6 Mike Rooney mxr@qvii.com

Cody Precord wrote:

Hello,

On 8/6/08, raffaello <barbarossa.platz@gmail.com mailto:barbarossa.platz@gmail.com> wrote:

I tried to do the same thing, and the text width is easily

calculated with



def CalcStaticWidth(ParentWindow, text):

    """The function calculates the width of the  wx.StaticText

    containing completely «text», with the standard font of

ParentWindow"""

    st = wx.StaticText(ParentWindow, wx.ID_ANY, text)

    width = st.Size.width

    st.Close(True)

    st.Destroy()

    return width

FYI: You can do this in a much easier way by using GetTextExtent.

txt_w, txt_h = ParentWindow.GetTextExtent(text)

This isn’t a terrible solution, as I could use that and then add a liberal amount of pixels to account for the drop-down button and it would probably be better. Although it seems like there should be a way to make the control size itself appropriately.

  • Mike

wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Mike Rooney wrote:

Hello,

I am noticing that my ComboBoxes are being a little greedy with their MinSize, as per the attached screenshot. I have noticed that controls seem to have a "minimum minimum size".

With GTK there is a concept similar to minimum or best size for widgets, and the wxGTK code uses that when calculating the wx best size.

Of course I can set their Sizes manually but then I am not accommodating for all the possible scenarios that would change the text size (themes/fonts/dpi/etc).

Is there either a way to make them actually size in a more compact manner, or manually do the calculation by getting the width of the text and then the width of the drop-down button?

You can assume that the button is nearly square, so if you take the default height of the combo and add that to with width you'll be pretty close.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I applied all these ideas to a subclass of wx.Combo, (see the method Compact()). On Windows XP it runs properly, and the ComboBox is reduced to the indispensable width. If anybody can try it on Mac and/or Linux, please let me know the result.

If some finds any use for the subclassed ComboBox itself, the code is obviously open source

rbcombo.py (9 KB)

···

2008/8/7 Robin Dunn robin@alldunn.com

Mike Rooney wrote:

Hello,

I am noticing that my ComboBoxes are being a little greedy with their MinSize, as per the attached screenshot. I have noticed that controls seem to have a “minimum minimum size”.

With GTK there is a concept similar to minimum or best size for widgets, and the wxGTK code uses that when calculating the wx best size.

Of course I can set their Sizes manually but then I am not accommodating for all the possible scenarios that would change the text size (themes/fonts/dpi/etc).

Is there either a way to make them actually size in a more compact manner, or manually do the calculation by getting the width of the text and then the width of the drop-down button?

You can assume that the button is nearly square, so if you take the default height of the combo and add that to with width you’ll be pretty close.

Robin Dunn

Software Craftsman

http://wxPython.org Java give you jitters? Relax with wxPython!


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

raffaello wrote:

I applied all these ideas to a subclass of wx.Combo, (see the method Compact()). On Windows XP it runs properly, and the ComboBox is reduced to the indispensable width. If anybody can try it on Mac and/or Linux, please let me know the result.

If some finds any use for the subclassed ComboBox itself, the code is obviously open source

Okay, I am not sure I understand your "subclass", it seems like you are redefining all the methods, or something. You should only need to define over-ridden methods in your subclass. But anyway your Compact method was pretty good, thanks! I cleaned it up a bit and here is how I implemented the subclass:

class CompactableComboBox(wx.ComboBox):
    def Compact(self):
        # Calculates and sets the minimum width of the ComboBox.
        # Width is based on the width of the longest string.
        # From the ideas of Mike Rooney, Cody Precord, Robin Dunn and Raffaello.
        comboStrings = self.Strings
        if len(comboStrings) == 0:
            self.SetMinSize(wx.DefaultSize)
        else:
            height = self.Size[1]
            maxTextWidth = max([self.Parent.GetTextExtent(s.strip())[0] for s in comboStrings])
            self.SetMinSize((maxTextWidth + height + 10, height))

Then all I did was use CompactableComboBox instead and call Compact() before the main Layout. Note that I had to add 10 to it, to compensate for borders, text padding, et cetera, otherwise the last character of the longest string was cut off. It looks pretty good here on GTK!

Thanks everyone!
- Mike