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?
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.
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?
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.
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?
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?
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.
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
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.
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!