Center text vertically in TextCtrl

I am trying to center the text inside a TextCtrl. Many solutions to other similar questions rely on using ALIGN_CENTER_VERTICAL however I cannot do this as I want my text box to be larger than the font height.

This is what I am trying now:

self.name_tb = wx.TextCtrl(self.showing_panel, style=wx.BORDER_NONE | wx.TE_CENTRE)
self.showing_sizer.Add(self.name_tb, 1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=3)
self.name_tb.SetMinSize((-1, height))  # height > font height

image

Desired outcome is that the text and the cursor is aligned vertically centered.

This has been asked before here however that answer centers the text horizontally, not vertically: Vertically center text in a wx.TextCtrl widget

When I run the code below using wxPython 4.2.1 + Python 3.10.12 + Linux Mint 21.3, the text is centred vertically.

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        self.SetSize((400, 200))
        self.SetTitle("Centre Text Vertically")
        self.panel = wx.Panel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.text_ctrl = wx.TextCtrl(self.panel, wx.ID_ANY, "", style=wx.TE_CENTRE)
        self.text_ctrl.SetMinSize((150, 50))
        sizer.Add(self.text_ctrl, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 40)
        self.panel.SetSizer(sizer)
        self.Layout()

        wx.CallAfter(self.displayText)

    def displayText(self):
        self.text_ctrl.SetValue("Text Text Text")
        self.text_ctrl.SetInsertionPointEnd()


if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

Screenshot at 2024-06-21 20-20-31

Thank you so much @RichardT . This is what I get running your code - I think it’s an OS issue. Do you have any idea on how to achieve this on a Mac?

I have just tested my example code on my MacBook Pro and get the same results as you. I am not aware of a way to get the TextCtrl to do what you want on a Mac. I tried using the SetMargins() method, but that only seems to work on Windows.

One possible workaround would be to adapt the technique I posted in How to make padding around the text of TextCtrl? - #4 by RichardT. That example was for a multiline TextCtrl so you would need to remove the wx.TE_MULTILINE style.

Thank you Richard - that seems to do the trick. One little niggle though: for the non wx.TE_MULTILINE style, a blue focus border appears when you click on it. Is there any way to make this not happen as with the Panel approach, the blue focus border shows that it is a hack:
(top is multiline, bottom is singleline)

Ah I got it: self.text_ctrl.EnableVisibleFocus(False)

Thanks so much @RichardT, you’re too good to me!