Textctrl in 4.2.1 smaller than in 4.2.0

I updated from 4.2.0 to 4.2.1. Now all textctrl are painted smaller than other controls.
I use Xubuntu 22.04 and python 3.10.

wxTextCtrlSmaller

How you can fix this?

Thanks and best regards,

perthil

Hi & welcome to Discuss wxPython.

I must admit that I hadn’t noticed any difference in the default size of wx.TextCtrl when I upgraded from 4.2.0 to 4.2.1.
I use the Mate desktop on Linux Mint 21.2 and python 3.10.

Therefore, I have just created a simple app in wxGlade containing a similar set of controls to your screen dump:

import wx


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((400, 300))
        self.SetTitle("TextCtrl Size")
        self.panel = wx.Panel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.combo_box = wx.ComboBox(self.panel, wx.ID_ANY, choices=[], style=wx.CB_DROPDOWN)
        sizer.Add(self.combo_box, 0, 0, 0)
        self.spin_ctrl = wx.SpinCtrl(self.panel, wx.ID_ANY, "0", min=0, max=100)
        sizer.Add(self.spin_ctrl, 0, 0, 0)
        self.spin_ctrl_double = wx.SpinCtrlDouble(self.panel, wx.ID_ANY, initial=0, min=0.0, max=100.0)
        self.spin_ctrl_double.SetDigits(2)
        sizer.Add(self.spin_ctrl_double, 0, 0, 0)
        self.text_ctrl = wx.TextCtrl(self.panel, wx.ID_ANY, "")
        sizer.Add(self.text_ctrl, 0, 0, 0)
        self.choice = wx.Choice(self.panel, wx.ID_ANY, choices=[])
        sizer.Add(self.choice, 0, 0, 0)

        self.get_sizes_button = wx.Button(self.panel, wx.ID_ANY, "Get Sizes")
        sizer.Add(self.get_sizes_button, 0, wx.TOP, 20)

        self.panel.SetSizer(sizer)
        self.Layout()

        self.Bind(wx.EVT_BUTTON, self.OnGetSizes, self.get_sizes_button)


    def OnGetSizes(self, _event):
        for name, ctrl in (("ComboBox", self.combo_box),
                           ("SpinCtrl", self.spin_ctrl),
                           ("SpinCtrlDouble", self.spin_ctrl_double),
                           ("TextCtrl", self.text_ctrl),
                           ("Choice", self.choice)):
            print("%16s: %s" % (name, ctrl.GetSize()))

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

Here is what it looks like using the TraditionalOk theme:

TraditionalOk_4.2.1

When you click on the “Get Sizes” button, it prints the sizes of the controls on the command line.

I then ran the app using the TraditionalOk theme, followed by the Mint-L theme on a PC running 4.2.0 and then on a PC running 4.2.1

Here is a summary of the results:

TraditionalOk Theme
-------------------
        wxPython 4.2.0               wxPython 4.2.1

        ComboBox: (113, 26)          ComboBox: (113, 26)
        SpinCtrl: (97, 30)           SpinCtrl: (97, 30)
  SpinCtrlDouble: (121, 30)    SpinCtrlDouble: (121, 30)
        TextCtrl: (89, 27)           TextCtrl: (89, 28)
          Choice: (109, 26)            Choice: (109, 26)

Mint-L Theme
------------
        wxPython 4.2.0               wxPython 4.2.1

        ComboBox: (135, 30)          ComboBox: (135, 30)
        SpinCtrl: (119, 34)          SpinCtrl: (119, 34)
  SpinCtrlDouble: (139, 34)    SpinCtrlDouble: (139, 34)
        TextCtrl: (97, 28)           TextCtrl: (97, 31)
          Choice: (123, 30)            Choice: (123, 30)

This shows that using different themes has a much bigger impact on the default sizes, than changing the wxPython version has.

For the TextCtrl, the height increased by one pixel going from 4.2.0 to 4.2.1 using the TraditionalOk theme.
However, its height increased by 3 pixels going from 4.2.0 to 4.2.1 using the Mint-L theme.

[Note: Linux Mint uses X11, whereas Ubuntu uses Wayland by default. However, I don’t know if it makes any difference to the default sizes of these controls.]

When I use single line TextCtrls in an application I don’t tend to change their height. Sometimes I do change the width using SetMinSize().

If I have a single line TextCtrl in a horizontal BoxSizer with other controls of different height, I will usually specify wx.ALIGN_CENTER_VERTICAL when adding each control to the sizer, rather than trying to force them to all be the same height.

Hi,

May be that the theme has an impact too. But, I didn’t change it. All I did, was an update of wx.

I tried your program and yes, there is a difference because of the theme. But in both themes I tested the textctrl is much smaller than the others. The height difference is 8 pixels.

In 4.2.0 all controls have 34 pixels, in 4.2.1 textctrl has 26 pixels, all others have 34. In the picture the theme is the same, but not dark. But dark or clear is the same. In 4.2.1 the textctrl looks like a button with EXACTFIT.

wxTextCtrlTest420_adwaita

Because the theme is always the same, I think it is doesn’t depend on the theme, there must be another reason.

The first question users ask if they see this is always why is this one smaller? I like to avoid this.

I already have many windows. Therefore I search for a possibility to make the controls having all the same height without changing everything. Something like a default height for all controls? Any idea?

Thanks

I’ve had a look, but have not found anything built into wxPython that would make a set of controls all have the same height.

The only thing I can think of is to create your own function that finds the maximum dimensions of all the controls concerned and then set all of them to that size.

Below is an example that sets both the widths and heights to be the same. If you only want to set one dimension you can pass -1 as the other dimension e.g. SetMinSize((-1, max_h)) and not bother to build up the list for that dimension.

import wx

def equaliseSizes(ctrls):
    widths = []
    heights = []
    for ctrl in ctrls:
        w, h = ctrl.GetSize()
        widths.append(w)
        heights.append(h)
    max_w = max(widths)
    max_h = max(heights)
    for ctrl in ctrls:
        ctrl.SetMinSize((max_w, max_h))


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((400, 300))
        self.SetTitle("TextCtrl Size")
        self.panel = wx.Panel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.combo_box = wx.ComboBox(self.panel, wx.ID_ANY, choices=[], style=wx.CB_DROPDOWN)
        sizer.Add(self.combo_box, 0, 0, 0)
        self.spin_ctrl = wx.SpinCtrl(self.panel, wx.ID_ANY, "0", min=0, max=100)
        sizer.Add(self.spin_ctrl, 0, 0, 0)
        self.spin_ctrl_double = wx.SpinCtrlDouble(self.panel, wx.ID_ANY, initial=0, min=0.0, max=100.0)
        self.spin_ctrl_double.SetDigits(2)
        sizer.Add(self.spin_ctrl_double, 0, 0, 0)
        self.text_ctrl = wx.TextCtrl(self.panel, wx.ID_ANY, "")
        sizer.Add(self.text_ctrl, 0, 0, 0)
        self.choice = wx.Choice(self.panel, wx.ID_ANY, choices=[])
        sizer.Add(self.choice, 0, 0, 0)

        self.get_sizes_button = wx.Button(self.panel, wx.ID_ANY, "Get Sizes")
        self.Bind(wx.EVT_BUTTON, self.OnGetSizes, self.get_sizes_button)
        sizer.Add(self.get_sizes_button, 0, wx.TOP, 20)

        self.panel.SetSizer(sizer)
        self.Layout()
        self.Show()
        ctrls = (self.combo_box, self.spin_ctrl,
                 self.spin_ctrl_double,
                 self.text_ctrl, self.choice)
        equaliseSizes(ctrls)
        self.Layout()

    def OnGetSizes(self, _event):
        for name, ctrl in (("ComboBox", self.combo_box),
                           ("SpinCtrl", self.spin_ctrl),
                           ("SpinCtrlDouble", self.spin_ctrl_double),
                           ("TextCtrl", self.text_ctrl),
                           ("Choice", self.choice)):
            print("%16s: %s" % (name, ctrl.GetSize()))

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        return True

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

Tested using Python 3.10.12 + wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1 on Linux Mint 21.2

        ComboBox: (121, 30)
        SpinCtrl: (121, 30)
  SpinCtrlDouble: (121, 30)
        TextCtrl: (121, 30)
          Choice: (121, 30)

Screenshot at 2023-08-26 20-36-10

Thank you.

I use wxGlade, so I have to add some extra code for every control. Seems to be the best solution.

Maybe that it is a problem of wxWidgets. The used versions are also different (3.2.1 and 3.2.2.1).

Best regards.

Make a 32x32 image. If that image fails, then use make parametric one. One that scales…

Same problem to update from Ubuntu 20.04 to 22.04

Ubuntu 22.04 Python 3.10.12 wxPython 4.2.1 wxWidgets 3.0.5.1

error_size_TextCtrl

wxformbuilder 4.0.0 run (work fine)
size_TextCtrl_ok

Set TextCtrl height is not a solution for me. The project has many textCtrl in multiple forms.

I replaced the wxpython version 4.2.1 with the 4.1.1 version and it now works correctly.

I raised an issue in the wxGlade GitHub repository last month concerning a possibly related issue:

@DietmarSchwertberger investigated the issue and found that there were several changes made to the function wxTextCtrl::DoGetSizeFromTextSize for gtk in wxWidgets 3.2.1. He has produced a workaround for these changes for wxGlade.

There has also been another issue raised in the wxPython GitHub repo which may be related:

The issue should be fixed in the current repository version / next release, as on November 14th Scott did update wx to a more recent version.
For MacOs there are recent snapshots available. Please test and report if there is still a problem. The behaviour is slightly different from 3.1.0.

Good,

I installed wxpython inside a virtual environment with venv using pip.
Is there a way to test the nightly version from pip?
Apologies for my ignorance.
Thank you!

Yes, see Index of /Phoenix/snapshot-builds although it looks like only the macOS auto-builder is working right now it seems.

Sorry, what package is for ubuntu 22.04?
(For install with pip)

wxPython-4.2.2a1.dev5654+0c545000-cp39-cp39-macosx_10_10_universal2.whl 2024-01-11 02:45 30M
wxPython-4.2.2a1.dev5654+0c545000-cp310-cp310-macosx_10_10_universal2.whl 2024-01-11 01:55 30M
wxPython-4.2.2a1.dev5654+0c545000-cp311-cp311-macosx_10_10_universal2.whl 2024-01-11 02:11 30M
wxPython-4.2.2a1.dev5654+0c545000-cp312-cp312-macosx_10_10_universal2.whl
Thank you!