Search code examples
pythonwxpython

Creating multiple Frames in for loop wxPython


I am new to wxPython. I have multiple records in a file and each record has to be read from the file and displayed in different frames. I am trying to create frames in for loop, but I want the second frame to be created only after the first frame has been destroyed. Below is my code:

import wx
import textentry

class Frame(wx.Frame):  
    def __init__(self, fargs, **kwargs):
        wx.Frame.__init__(self, fargs, **kwargs)
        #self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.panel = wx.Panel(self)
        self.box = wx.BoxSizer(wx.VERTICAL)

        self.m_text = wx.StaticText(self.panel, -1, label = suggested.lstrip())
        self.m_text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.m_text.SetSize(self.m_text.GetBestSize())
        self.box.Add(self.m_text, 0, wx.ALL, 10)


        self.filler_text = wx.StaticText(self.panel, -1, "************ Description ****************")
        self.filler_text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.filler_text.SetSize(self.filler_text.GetBestSize())
        self.box.Add(self.filler_text, 0, wx.ALL, 10)



        self.d_text = wx.StaticText(self.panel, -1, label = description.lstrip())
        self.d_text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.d_text.SetSize(self.d_text.GetBestSize())
        self.box.Add(self.d_text, 0, wx.ALL, 10)

        self.m_close = wx.Button(self.panel, wx.ID_EDIT, "Edit")
        self.m_close.Bind(wx.EVT_BUTTON, self.onReject)
        self.box.Add(self.m_close, 0, wx.ALL, 10)

        self.m_skip = wx.Button(self.panel, wx.ID_EDIT, "Skip")
        self.m_skip.Bind(wx.EVT_BUTTON, self.onSkip)
        self.box.Add(self.m_skip, 0, wx.ALL, 10)

        self.m_accept = wx.Button(self.panel, wx.ID_YES, "Accept")
        self.m_accept.Bind(wx.EVT_BUTTON, self.OnAccept)
        self.box.Add(self.m_accept, 0, wx.ALL, 10)
        self.box.SetSizeHints(self)
        self.panel.SetSizer(self.box)
        self.panel.Layout()

    def onReject(self, event):
        dialog = textentry.TextEntryDialog(None, 'Edit License Info', 'Enter License information')
        dialog.Center()
        dialog.SetValue(self.m_text.GetLabel())
        if dialog.ShowModal() == wx.ID_OK:
            self.m_text.SetLabel(dialog.GetValue())
            self.box.SetSizeHints(self)
            self.panel.Layout()
            dialog.Destroy()

    def onSkip(self, event):
        self.Destroy()

    def OnClose(self, event):
        dlg = wx.MessageDialog(self,"Do you really want to close this application?","Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
        result = dlg.ShowModal()
        dlg.Destroy()
        if result == wx.ID_OK:
            self.Destroy()

    def OnAccept(self, event):
        f = open("AcceptedLicense.txt", "a")
        print self.m_text.GetLabel().encode('utf-8')
        f.write(self.m_text.GetLabel().encode('utf-8') + '\n')
        f.close()
        self.Destroy()

panel =''
app = wx.App(False)
f = open("License.txt", "r")
main_message = f.read()
f.close()
if main_message != None:
    for m in main_message.split('Suggested License Text:'):
        if m != "":
            desc = [d for d in m.split("Description:")]
            suggested = desc[0]
            description = desc[1]
            top = Frame(None)
            top.Show()
app.MainLoop()

This is the code I use to create multiple frames:

if main_message != None:
    for m in main_message.split('Suggested License Text:'):
        if m != "":
            desc = [d for d in m.split("Description:")]
            suggested = desc[0]
            description = desc[1]
            top = Frame(None)
            top.Show()

Any help is much appreciated.


Solution

  • You need to start app.MainLoop() before the frames will show. In your code all the frames are created before MainLoop() is run, that's why the frames are all displayed at once. Rather than creating multiple frames, create multiple panels, just hide the previous ones.

    Also to control the creation of frames, try returning something, in the event handlers before destroy() function call. And in the main frame check for the return to create the next panel.