1.11M Members

wxpython: Panel immediatly opens, closes, then segfaults and dies

 
0
 

The title explains most of it. at the point in the code where this frame gets created it immediately opens, closes, then segfaults, and the whole program dies. the program worked find before this frame was added and the only code using this frame from outside of it is the constructor.
It prints "done" and then dies.

emailDiag=EnterEmail(self,-1,'email win')

help would be greatly appreciated

class EnterEmail(wx.Frame):
    def __init__(self, parent,id,title):
        wx.Frame.__init__(self,parent,id,title,size=(RESOLUTION[0]/1.5,RESOLUTION[1]/1.5))
        self.parent=parent
        font5 = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL)
        font3 = wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)
        font1 = wx.Font(24, wx.SWISS, wx.NORMAL, wx.BOLD,True)
        self.SetBackgroundColour('#f2f200')
        
        
        sizer=wx.BoxSizer(wx.VERTICAL)
        panel0=wx.Panel(self,-1)
        panel1=wx.Panel(self,-1)
        hsizer=wx.BoxSizer(wx.HORIZONTAL)
        vsizer=wx.BoxSizer(wx.VERTICAL)
        vsizer2=wx.BoxSizer(wx.VERTICAL)
        
        infoLabel = wx.StaticText(self, -1, "Enter your phone and/or email information.")
        infoLabel.SetFont(font3)

        emailLabel=wx.StaticText(self,-1,"Email")
        emailLabel.SetFont(font1)
        emailBoxLabel=wx.StaticText(self,-1,"Enter your e-mail address:")
        emailBoxLabel.SetFont(font5)
        
        self.email = wx.TextCtrl(self, -1, size=(300, 30))
        self.email.SetFont(font3)
        
        emailBoxLabel2=wx.StaticText(self,-1,"Confirm e-mail address:")
        emailBoxLabel2.SetFont(font5)
        self.confirmEmail = wx.TextCtrl(self, -1, size=(300, 30))
        self.confirmEmail.SetFont(font3)

        phoneLabel=wx.StaticText(self,-1,"Phone")
        phoneLabel.SetFont(font1)

        carrierLabel=wx.StaticText(self,-1,"Please select your service provider:")
        carrierLabel.SetFont(font5)
        self.carrierChoice=wx.Choice(self,-1,size=(300,30))
        self.carrierChoice.SetFont(font3)
        self.carrierChoice.AppendItems(strings=CARRIERS)

        numberLabel=wx.StaticText(self,-1,"Enter your phone number:")
        numberLabel.SetFont(font5)
        self.number= wx.TextCtrl(self, -1, size=(300, 30))
        self.number.SetFont(font3)

        self.sendButton=wx.Button(self, -1,"Send",size=(150,30))
        self.Bind(wx.EVT_BUTTON, self.OnSubmit, self.sendButton)
        
        self.startOverBut=wx.Button(self,-1,"Cancel",size=(150,30))
        self.Bind(wx.EVT_BUTTON,self.OnClose(),self.startOverBut)
        
        #hooking it all together
        vsizer.Add(emailLabel,0,wx.TOP|wx.ALIGN_CENTER,5)
        vsizer.Add(emailBoxLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer.Add(self.email,0,wx.TOP|wx.ALIGN_CENTER,10)
        vsizer.Add(emailBoxLabel2,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer.Add(self.confirmEmail,0,wx.TOP|wx.ALIGN_CENTER,10)
        
        vsizer2.Add(phoneLabel,0,wx.TOP|wx.ALIGN_CENTER,5)
        vsizer2.Add(carrierLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer2.Add(self.carrierChoice,0,wx.TOP|wx.ALIGN_CENTER,10)
        vsizer2.Add(numberLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer2.Add(self.number,0,wx.TOP|wx.ALIGN_CENTER,10)

        vsizer.Add(self.startOverBut,0,wx.TOP|wx.EXPAND,25)
        vsizer2.Add(self.sendButton,0,wx.TOP|wx.EXPAND,25)
        
        sizer.Add(infoLabel, 0, wx.TOP|wx.ALIGN_CENTER, 5)
        panel0.SetSizer(vsizer)
        panel1.SetSizer(vsizer2)
        hsizer.Add(vsizer,0,wx.LEFT|wx.ALIGN_LEFT,5)
        hsizer.Add(vsizer2,0,wx.LEFT|wx.ALIGN_RIGHT,5)
        
        
        
        sizer.Add(hsizer)
        self.SetSizer(sizer)
        
        self.Centre()
        self.Bind(wx.EVT_TIMER, self.OnUpdateTimer)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow())
        self.Show(True)
        print 'done '
    def OnSubmit(self,event):
        pass
    def OnUpdateTimer(self,evt):
        pass
    def OnClose(self):
####        self.email.Destroy()
####        self.confirmEmail.Destroy()
####        self.carrierChoice.Destroy()
####        self.number.Destroy()
####        self.sendButton.Destroy()
####        self.startOverBut.Destroy()

        self.Close(True)

    def OnCloseWindow(self):
        self.Destroy()
 
1
 

You are coding the button callback incorrectly. When you produce 102 lines of code with no testing, it is very difficult to find which line is segfaulting amongst all that code. Apparently no one else wanted to sift through all of this either. For starters, break this up using functions so you can test each function individually. The variables "RESOLUTION" and "CARRIERS" have not been declared in this class, so you will get an error. Note that the following program runs, but obviously still requires some work.

import wx

class EnterEmail(wx.Frame):
    def __init__(self, parent,id,title):
##        wx.Frame.__init__(self,parent,id,title,size=(RESOLUTION[0]/1.5,RESOLUTION[1]/1.5))
        wx.Frame.__init__(self,parent,id,title)
        self.parent=parent
        font5 = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL)
        font3 = wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)
        font1 = wx.Font(24, wx.SWISS, wx.NORMAL, wx.BOLD,True)
        self.SetBackgroundColour('#f2f200')
 
 
        sizer=wx.BoxSizer(wx.VERTICAL)
        panel0=wx.Panel(self,-1)

        infoLabel = wx.StaticText(panel0, -1, "Enter your phone and/or email information.")
        infoLabel.SetFont(font3)
 
        """
        panel1=wx.Panel(self,-1)
        hsizer=wx.BoxSizer(wx.HORIZONTAL)
        vsizer=wx.BoxSizer(wx.VERTICAL)
        vsizer2=wx.BoxSizer(wx.VERTICAL)
 
        emailLabel=wx.StaticText(self,-1,"Email")
        emailLabel.SetFont(font1)

        emailBoxLabel=wx.StaticText(self,-1,"Enter your e-mail address:")
        emailBoxLabel.SetFont(font5)

        self.email = wx.TextCtrl(self, -1, size=(300, 30))
        self.email.SetFont(font3)
 
        emailBoxLabel2=wx.StaticText(self,-1,"Confirm e-mail address:")
        emailBoxLabel2.SetFont(font5)
        self.confirmEmail = wx.TextCtrl(self, -1, size=(300, 30))
        self.confirmEmail.SetFont(font3)
 
        phoneLabel=wx.StaticText(self,-1,"Phone")
        phoneLabel.SetFont(font1)
 
        carrierLabel=wx.StaticText(self,-1,"Please select your service provider:")
        carrierLabel.SetFont(font5)
        self.carrierChoice=wx.Choice(self,-1,size=(300,30))
        self.carrierChoice.SetFont(font3)
        CARRIERS = ["abc", "def", "hij"]
        self.carrierChoice.AppendItems(strings=CARRIERS)
 
        numberLabel=wx.StaticText(self,-1,"Enter your phone number:")
        numberLabel.SetFont(font5)
        self.number= wx.TextCtrl(self, -1, size=(300, 30))
        self.number.SetFont(font3)
        """ 
        self.sendButton=wx.Button(panel0, -1,"Send", (30,30))
        self.sendButton.Bind(wx.EVT_BUTTON, self.OnSubmit)
        """ 
        self.startOverBut=wx.Button(self,-1,"Cancel",size=(150,30))
        self.Bind(wx.EVT_BUTTON,self.OnClose,self.startOverBut)
 
        #hooking it all together
        vsizer.Add(emailLabel,0,wx.TOP|wx.ALIGN_CENTER,5)
        vsizer.Add(emailBoxLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer.Add(self.email,0,wx.TOP|wx.ALIGN_CENTER,10)
        vsizer.Add(emailBoxLabel2,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer.Add(self.confirmEmail,0,wx.TOP|wx.ALIGN_CENTER,10)
 
        vsizer2.Add(phoneLabel,0,wx.TOP|wx.ALIGN_CENTER,5)
        vsizer2.Add(carrierLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer2.Add(self.carrierChoice,0,wx.TOP|wx.ALIGN_CENTER,10)
        vsizer2.Add(numberLabel,0,wx.TOP|wx.ALIGN_CENTER,25)
        vsizer2.Add(self.number,0,wx.TOP|wx.ALIGN_CENTER,10)
 
        vsizer.Add(self.startOverBut,0,wx.TOP|wx.EXPAND,25)
        vsizer2.Add(self.sendButton,0,wx.TOP|wx.EXPAND,25)
 
        sizer.Add(infoLabel, 0, wx.TOP|wx.ALIGN_CENTER, 5)
        panel0.SetSizer(vsizer)
        panel1.SetSizer(vsizer2)
        hsizer.Add(vsizer,0,wx.LEFT|wx.ALIGN_LEFT,5)
        hsizer.Add(vsizer2,0,wx.LEFT|wx.ALIGN_RIGHT,5)
 
 
 
        sizer.Add(hsizer)
        self.SetSizer(sizer)
 
        self.Centre()
        self.Bind(wx.EVT_TIMER, self.OnUpdateTimer)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow())
        """

        self.Show(True)
        print 'done '

    def OnSubmit(self,event):
        print "OnSubmit called"

    def OnUpdateTimer(self,evt):
        pass

    def OnClose(self):
####        self.email.Destroy()
####        self.confirmEmail.Destroy()
####        self.carrierChoice.Destroy()
####        self.number.Destroy()
####        self.sendButton.Destroy()
####        self.startOverBut.Destroy()
 
        self.Close(True)
 
    def OnCloseWindow(self):
        self.Destroy()

app = wx.App()
EM = EnterEmail(None, -1, 'EMail Test')
app. MainLoop()
 
0
 

The Lardmeister submitted this example in the "Starting wxPython" sticky which I think does something similar to what you want.

# a simple mortgage calulator using wxPython
# checked it out with the online mortgage calculator at:
# http://www.mortgage-calc.com/mortgage/simple.php
 
import wx
import math
 
class MyFrame(wx.Frame):
    """frame and widgets to handle input and output of mortgage calc"""
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        # add panel, labels, text and sizer widgets
        panel = wx.Panel(self, -1)
        panel.SetBackgroundColour('green')
        label1 = wx.StaticText(panel, -1, "Enter total loan amount:")
        label2 = wx.StaticText(panel, -1, "Enter annual interest (%):")
        label3 = wx.StaticText(panel, -1, "Enter years to pay:")
        self.loan = wx.TextCtrl(panel, -1, "100000")
        self.interest = wx.TextCtrl(panel, -1, "6.5")
        self.years = wx.TextCtrl(panel, -1, "30")
        self.calc_btn = wx.Button(panel, -1, ' Perform Mortgage Calculation ')
        self.calc_btn.SetBackgroundColour('light blue')
        self.calc_btn.Bind(wx.EVT_BUTTON, self.onCalc)
        info = "Modify the above data to your needs!"
        self.result = wx.TextCtrl(panel, -1, info, size=(290, 100), 
            style=wx.TE_MULTILINE)
 
        # use gridbagsizer for layout of widgets
        sizer = wx.GridBagSizer(vgap=5, hgap=10)
        sizer.Add(label1, pos=(0, 0))
        sizer.Add(self.loan, pos=(0, 1))  # row 0, column 1
        sizer.Add(label2, pos=(1, 0))
        sizer.Add(self.interest, pos=(1, 1))
        sizer.Add(label3, pos=(2, 0))
        sizer.Add(self.years, pos=(2, 1))
        sizer.Add(self.calc_btn, pos=(3, 0), span=(1, 2))
        # span=(1, 2) --> allow to span over 2 columns 
        sizer.Add(self.result, pos=(4, 0), span=(1, 2))
 
        # use boxsizer to add border around sizer
        border = wx.BoxSizer()
        border.Add(sizer, 0, wx.ALL, 20)
        panel.SetSizerAndFit(border)
        self.Fit()
 
    def onCalc(self, event):
        """do the mortgage calcuations"""
        # get the values from the input widgets
        principal = float(self.loan.GetValue())
        interest = float(self.interest.GetValue())
        years = float(self.years.GetValue())
        # calculate        
        interestRate = interest/(100 * 12)
        paymentNum = years * 12
        paymentVal = principal * \
            (interestRate/(1-math.pow((1+interestRate), (-paymentNum))))
        # show the result
        resultStr1 = "Your monthly payment will be $%.2f for\n" % paymentVal
        resultStr2 = "a %.1f year $%.2f loan at %.2f%s interest" % \
            (years, principal, interest, '%') 
        self.result.SetValue(resultStr1 + resultStr2) 
 
 
app = wx.App()
frame = MyFrame(None, -1, "Mortgage Calculator")
frame.Show()
app.MainLoop()
 
0
 

thank you very much, I hadn't realized I was binding the buttons incorrectly. I realize that it was probably harder to work with the code that I posted due to it only being a part of a whole and I am very grateful.

 
0
 

but i dont see any prolem with binding a button to self.
Infact i think its a good idea. Well not to start te holy war here but but that is my view

self.Bind(wx.EVT_BUTTON, self.OnSubmit, self.sendButton)

have alot of advantages....

 
0
 

well I'll try it the other way and see if that helps.

 
0
 

Since you have 2 panels, the button should go in one of them. Container widgets are there for a reason. Once again, take a look at Lardmeister's code, especially how the panel container is used

 
0
 

Yeah I was misunderstanding how the panels worked, but I fixed it and it works now thanks everyone.

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: