Search code examples
pythonwxpython

How can I indicate a specific TextCtrl within a window frame and print to it, based on program result, on wxPython?


I want to print an info text to a TextCtrl widget specified by the program itself and don't know how. I only know how to do this 'manually' (let's say with a part of the program that do self.text_ctrl_5.SetLabel("blah") or self.text_ctrl_27.SetLabel("blah") respectively), but I have no idea how to instruct the program to do that by itself, I mean if condition A -> then print specifically to text_ctrl_5, if condition B -> then print specifically to text_ctrl_27.

For just 2-3 positions I can expand the line code (create one print instruction dedicated for each text_ctrl), but for 16 or 24 entries I am looking for some compact solution.

Suppose I have this two text positions to display, which are just part of a bigger window frame, how can I instruct the program to print on specific position ? Let's say if today is Monday then print "mon" on text_ctrl_1 and if Tuesday then print "tue" on text_ctrl_2 ? (days of week condition is just for example, not the actual need; also the label to print could be the same on different positions (or not))

self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "")
self.text_ctrl_2 = wx.TextCtrl(self, wx.ID_ANY, "")

Solution

  • If you have 16-24 text boxes on one screen, then it's probably time to rethink your user interface. Simple is almost always better. I don't understand why you couldn't just print your messages to one or two multiline text boxes. But regardless, I think the easiest way to do this sort of thing with a dictionary. Here's an example:

    import random
    import wx
    
    ########################################################################
    class MyPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)
    
            self.text_ctrls = {}
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            for i in range(12):
                txt = wx.TextCtrl(self)
                self.text_ctrls[i] = txt
                sizer.Add(txt, 0, wx.ALL|wx.EXPAND, 5)
    
            btn = wx.Button(self, label="Update TextCtrls")
            btn.Bind(wx.EVT_BUTTON, self.onButton)
            sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
    
            self.SetSizer(sizer)
    
        #----------------------------------------------------------------------
        def onButton(self, event):
            """"""
            ctrls = self.text_ctrls.keys()
            choices = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"]
            for i in range(3):
                ctrl = random.choice(ctrls)
                self.text_ctrls[ctrl].SetValue(random.choice(choices))
    
    
    ########################################################################
    class MyFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, title="Test", size=(800,600))
            panel = MyPanel(self)
            self.Show()
    
    #----------------------------------------------------------------------
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyFrame()
        app.MainLoop()
    

    The basic idea is to create a series of text controls and add them to a dictionary. Then in the update button, we randomly choose a day of the week to apply to a randomly chosen text control.