Never did much stuff with "Classes" while still writing in VB6. :)

I have the following wxPython Class in my pyTC file

class InfoUUT(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: InfoUUT.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.label_1 = wx.StaticText(self, -1, "This TPS is for the following UUT")
        self.label_9 = wx.StaticText(self, -1, "Please Enter UUT Revision and Serial Number")
        self.label_2 = wx.StaticText(self, -1, " Manufacturer:")
        self.Man_Name = wx.StaticText(self, -1, "")
        self.label_3 = wx.StaticText(self, -1, " Model Number:")
        self.ModNumber = wx.StaticText(self, -1, "")
        self.label_4 = wx.StaticText(self, -1, " Revision:")
        self.Revision = wx.TextCtrl(self, -1, "")
        self.label_5 = wx.StaticText(self, -1, " Military Desgination:")
        self.MilDesig = wx.StaticText(self, -1, "")
        self.label_6 = wx.StaticText(self, -1, " Nomenclature:")
        self.Nomen = wx.StaticText(self, -1, "")
        self.label_7 = wx.StaticText(self, -1, " Part Number:")
        self.PartNo = wx.StaticText(self, -1, "")
        self.label_8 = wx.StaticText(self, -1, " Serial Number:")
        self.SerNo = wx.TextCtrl(self, -1, "")
        self.panel_1 = wx.Panel(self, -1)
        self.btnContinue = wx.Button(self, -1, "Continue")
        self.btnExit = wx.Button(self, -1, "Exit")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.onContinue, self.btnContinue)
        self.Bind(wx.EVT_BUTTON, self.onExit, self.btnExit)
        # end wxGlade

    def onContinue(self, event):
        print "onContinue Occured"
        TC_Config.UUT_SN = self.Revision.GetValue()
        TC_Config.UUT_Rev = self.SerNo.GetValue()
        TC_Config.TPS_Status = "Continue"
        self.Destroy()
        

    def onExit(self, event):
        print "onExit Occured"
        TC_Config.TPS_Status = "Exit"
        self.Destroy()


    def __set_properties(self):
        # begin wxGlade: InfoUUT.__set_properties
        self.SetTitle("UUT Information")
        self.SetSize((489, 393))
        self.SetBackgroundColour(wx.Colour(192, 192, 192))
        # self.label_1.SetBackgroundColour(wx.Colour(192, 192, 192))
        self.label_1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        # self.label_9.SetBackgroundColour(wx.Colour(192, 192, 192))
        self.label_9.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.label_2.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.Man_Name.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.label_3.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.ModNumber.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.label_4.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.label_5.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.MilDesig.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.label_6.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.Nomen.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.label_7.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.PartNo.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.label_8.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.SerNo.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.panel_1.SetBackgroundColour(wx.Colour(192, 192, 192))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: InfoUUT.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_1.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        sizer_1.Add(self.label_9, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        sizer_1.Add(self.label_2, 0, 0, 0)
        sizer_1.Add(self.Man_Name, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_3, 0, 0, 0)
        sizer_1.Add(self.ModNumber, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_4, 0, 0, 0)
        sizer_1.Add(self.Revision, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_5, 0, 0, 0)
        sizer_1.Add(self.MilDesig, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_6, 0, 0, 0)
        sizer_1.Add(self.Nomen, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_7, 0, 0, 0)
        sizer_1.Add(self.PartNo, 0, wx.EXPAND, 0)
        sizer_1.Add(self.label_8, 0, 0, 0)
        sizer_1.Add(self.SerNo, 0, wx.EXPAND, 0)
        sizer_2.Add(self.panel_1, 1, wx.EXPAND, 0)
        sizer_2.Add(self.btnContinue, 0, wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM, 0)
        sizer_2.Add(self.btnExit, 0, wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM, 0)
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

# end of class InfoUUT

There are two buttons onContinue and onExit. (Lines 23 & 24

My understanding of Classes is that when you instantiate an instance of a Class that Instance should stand alone...

so When I Create the Instance in my ptf file

def UUT_Info():
    if __name__ == "__main__":
        app = wx.PySimpleApp(0)
        wx.InitAllImageHandlers()
        Display = InfoUUT(None, -1, "")
        Display.Man_Name.SetLabel(" Intellipower, Inc.")
        Display.ModNumber.SetLabel(" IHT2KGACDC-2184")
        Display.MilDesig.SetLabel(" ")
        Display.Nomen.SetLabel(" SWAN-D UPS")
        Display.PartNo.SetLabel(" ")
        Display.SerNo.SetLabel(" 2KCAGDCI09390606")
        app.SetTopWindow(Display)
        Display.Show()
        app.MainLoop()

My Event Handler remains in the Base Class!!! (Lines 33 & 41)

My understanding is that this is *not* the best use of Classes...

So, My question is this how do I create an instance of the button event handlers specific to the Display Instance?

If I can do that that would preserve the Base Class for Multiple Uses across multiple threads instead of, as it is, it is locked into a single use with specific variables...

Recommended Answers

All 3 Replies

It has nothing to do with class instances, but with the self.destroy which shuts down wx. If you want to destroy/close one object only, then you must first create the object and then close/destroy it only. There is a "Starting wxPython" at the top of the threads that has examples of destroy. Also, simplify your code to start with. An example of destroying an object follows. Click on one of the buttons to destroy it.

import wx
 
class Test:
    def __init__(self):
        app = wx.App(False)
        self.app = app
        frame = wx.Frame(None, wx.ID_ANY, "Test App")
        panel = wx.Panel(frame)
        vboxsizer = wx.BoxSizer(wx.VERTICAL)
        self.frame = frame
        self.panel = panel
 
        self.grid = wx.GridSizer(rows=0, cols=3)

        self.button_dict = {}
        x = 10
        y = 20
        for j in range(5):
            print j, x, y
            b = wx.Button(panel, label="Remove Button %d" % (j), id=j, pos=(x, y))
            self.grid.Add(b)
            b.Bind(wx.EVT_BUTTON, self.removeButton)
            self.button_dict[j] = b
            x += 50
            if j == 2:
                x = 10
                y = 30 

        exit = wx.Button(panel, -1, 'Exit', (10, 200))
        exit.Bind(wx.EVT_BUTTON,  self.exit_this)

        vboxsizer.Add(self.grid, 1, border=2, flag=wx.EXPAND|wx.ALL)
        panel.SetSizer(vboxsizer)
        frame.Show(True)
 
        app.MainLoop()
 

    def removeButton(self,e):
        button_num = e.GetId()
        print "ID =", button_num, type(button_num)
        if button_num in self.button_dict:
            self.button_dict[button_num].Destroy()


    def exit_this(self, event):
        self.frame.Destroy()

if __name__ == "__main__":
    t = Test()

Also, you can clean up the code mess by creating the widgets using a simple tuple (NOT tested):

self.widgets_dict = {}
widgets_tup= (("label_1", "This TPS is for the following UUT"),
              ("label_9", "Please Enter UUT Revision and Serial Number"),
              ("label_2", " Manufacturer:"),
              ("Man_Name", "").
              ("label_3", " Model Number:"))
# etc
#
# then create the widget and link it's instance to it's name via a dictionary
for widget in widgets_tup:
    self.widgets_dict[widget[0]] = wx.StaticText(self, -1, widget[1])
#---------------------------------------------------------------------------------
# you could also include the font size and wx.BOLD or wx.NORMAL in the tuple and
# eliminate all but on of the following statements
self.label_1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
#
widgets_tup= (("label_1", "This TPS is for the following UUT". wx.NORMAL, 14),  etc.
for widget in widgets_tup:
    self.widgets_dict[widget[0]] = wx.StaticText(self, -1, widget[1])
    self.widgets_dict[widget[0]].SetFont(wx.Font(widgets_tup[3], wx.DEFAULT, wx.NORMAL, widgets_tup[2], 0, ""))
#
#---------------------------------------------------------------------------------
# and similarly for the second arg in these statements (the others don't change)
sizer_1.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

Actually, the self.destroy is one of the issues I was interested in, but, not they way it was answered...

When I create "Display" using the UUTInfo Class...

It would be preferrable to "kill" the GUI using Display.destroy (or whatever the correct equivalent is...)

However, once I am "up" in the GUI my ptf code doesn't "see" the events self.onContinue and self.onExit so it can't "destroy" the "Display" instance until after the self "dies".

What I want to do is move the event handling out to the "Display" instance of the "UUTInfo" class...

What I want to do is move the event handling out to the "Display" instance of the "UUTInfo" class

That would require some form of multiprocessing as you have two processes running at the same time; the wx application and the code that kills it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.