Search code examples
pythonwxpython

wx widget won't work (python)


I've written a script that should ask for two values and then display them in another window. It looks like this:

import wx

class Example(wx.Frame):

    def __init__(self, parent, title):
        super(Example, self).__init__(parent, title=title,
            size=(300, 200))

        self.InitUI()
        self.Centre()
        self.Show()

    def InitUI(self):

        panel = wx.Panel(self)

        sizer = wx.GridBagSizer(4, 2)

        text1 = wx.StaticText(panel, label="Set COM-ports")
        sizer.Add(text1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM,
            border=15)

        line = wx.StaticLine(panel)
        sizer.Add(line, pos=(1, 0), span=(1, 5),
            flag=wx.EXPAND|wx.BOTTOM, border=10)

        text2 = wx.StaticText(panel, label="Dispersion control port:")
        sizer.Add(text2, pos=(2, 0), flag=wx.ALIGN_RIGHT|wx.LEFT, border=10)

        tc1 = wx.TextCtrl(panel)
        sizer.Add(tc1, pos=(2, 1), flag=wx.LEFT, border=10)

        text3 = wx.StaticText(panel, label="GPS port:")
        sizer.Add(text3, pos=(3, 0),flag=wx.ALIGN_RIGHT|wx.LEFT, border=10)

        tc2 = wx.TextCtrl(panel)
        sizer.Add(tc2, pos=(3, 1), flag=wx.LEFT,border=10)

        button4 = wx.Button(panel, label="Start")
        sizer.Add(button4, pos=(4, 0), flag=wx.ALIGN_RIGHT)
        self.Bind(wx.EVT_BUTTON, self.read, button4)
        button4.SetDefault()

        button5 = wx.Button(panel, wx.ID_EXIT, label="Cancel")
        sizer.Add(button5, pos=(4, 1), flag=wx.ALIGN_LEFT|wx.LEFT, border=10)
        self.Bind(wx.EVT_BUTTON, self.OnQuitApp, id=wx.ID_EXIT)

        panel.SetSizer(sizer)

    def read(self, event):
        try:
            DispPort = int(float(self.tc1.GetValue()))
            GpsPort = int(float(self.tc2.GetValue()))
            wx.MessageDialog(self, "DispPort: %s\nGpsPort: %s"%(DispPort,GpsPort), "Number entered", wx.OK | wx.ICON_INFORMATION).ShowModal()
        except:
            wx.MessageDialog(self, "Enter a number", "Warning!", wx.OK | wx.ICON_WARNING).ShowModal()

    def OnQuitApp(self, event):

        self.Close()


if __name__ == '__main__':
    app = wx.App()
    Example(None, title="Start DisperseIt")
    app.MainLoop()

When I run it, it never shows the values in the new window that is created in the read() method, it allways goes to exception.

The script is greatly inspired by this example script, that works just fine:

import wx

class Frame(wx.Frame):
    def __init__(self,parent,id):
        wx.Frame.__init__(self, parent, id,
                          'Read Number',
                          size = (200,200),
                          style=wx.MINIMIZE_BOX | wx.RESIZE_BORDER
    | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
        self.initUI()

    def initUI(self):

        widgetPanel=wx.Panel(self, -1)

        Button = wx.Button(widgetPanel, -1, "Read", pos=(10,10), size=(30,30))

        self.Bind(wx.EVT_BUTTON, self.read, Button)
        Button.SetDefault()

        self.Text1 = wx.TextCtrl(widgetPanel, -1, "", pos=(10, 50),
                                size =(100,30), style=wx.TE_CENTER)

        self.Text1.SetFont(wx.Font(20, wx.DECORATIVE, wx.NORMAL, wx.NORMAL))

        self.Text2 = wx.TextCtrl(widgetPanel, -1, "", pos=(10, 90),
                                size =(100,30), style=wx.TE_CENTER)

        self.Text2.SetFont(wx.Font(20, wx.DECORATIVE, wx.NORMAL, wx.NORMAL))


    def read(self, event):
        try:
            var1 = int(float(self.Text1.GetValue()))
            var2 = int(float(self.Text2.GetValue()))
            wx.MessageDialog(self, "First Number: %s\nSecond number: %s\n"%(var1,var2), "Number entered", wx.OK | wx.ICON_INFORMATION).ShowModal()
        except:
            wx.MessageDialog(self, "Enter a number", "Warning!", wx.OK | wx.ICON_WARNING).ShowModal()


if __name__ == "__main__":
    app = wx.App(False)
    frame = Frame(parent=None,id=-1)
    frame.Show()
    app.MainLoop()

What is the difference? Why does one work and not the other?


Solution

  • currently you're getting an exception but you don't know what caused it, if you want to check it, try changing the except clause in the read function to:

    except Exception as e: 
        print e
    

    in the read finction, you'll get:

    'Example' object has no attribute 'tc1'
    

    because Example class does not have the tc1 property (it is definned locally for the InitUI function only). you have to change it so it is an object property change:

    tc1 = wx.TextCtrl(panel)
    sizer.Add(tc1, pos=(2, 1), flag=wx.LEFT, border=10)
    tc2 = wx.TextCtrl(panel)
    sizer.Add(tc2, pos=(2, 1), flag=wx.LEFT, border=10)
    

    to:

    self.tc1 = wx.TextCtrl(panel)
    sizer.Add(self.tc1, pos=(2, 1), flag=wx.LEFT, border=10)
    self.tc2 = wx.TextCtrl(panel)
    sizer.Add(self.tc2, pos=(2, 1), flag=wx.LEFT, border=10)