Wie kann ich eine Instanz einer Klasse in einer anderen Klasse in Python erstellen

StackOverflow https://stackoverflow.com/questions/273937

  •  07-07-2019
  •  | 
  •  

Frage

Ich versuche, Python und WxPython zu lernen. Ich habe ein SAS-Programmierer seit Jahren. Dieses OOP Zeug kommt langsam zusammen, aber ich bin immer noch unscharf auf viele der Konzepte. Unten ist ein Codeabschnitt. Ich versuche, einen Button-Klick zu verwenden, um eine Instanz einer anderen Klasse zu erstellen. Speziell-Ich habe mein Hauptfeld in einer Klasse, und ich wollte ein Sekundärfeld zu Beispiel, wenn ein Benutzer auf einem der Menüpunkte auf dem Hauptfeld angeklickt. Ich habe all diese Arbeit, wenn das Sekundärfeld nur eine Funktion war. Ich kann nicht scheinen, ti als Klasse zu arbeiten.

Hier ist der Code

import wx

class mainPanel(wx.Frame):
    def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, id, 'directEDGAR Supplemental Tools', size=(450, 450))
    wx.Panel(self,-1)
    wx.StaticText(self,-1, "This is where I will describe\n the purpose of these tools",(100,10))


    menubar = wx.MenuBar()
    parser = wx.Menu()
    one =wx.MenuItem(parser,1,'&Extract Tables  with One Heading or Label')
    two =wx.MenuItem(parser,1,'&Extract Tables  with Two Headings or Labels')
    three =wx.MenuItem(parser,1,'&Extract Tables  with Three Headings or Labels')
    four =wx.MenuItem(parser,1,'&Extract Tables  with Four Headings or Labels')
    quit = wx.MenuItem(parser, 2, '&Quit\tCtrl+Q')
    parser.AppendItem(one)
    parser.AppendItem(two)
    parser.AppendItem(three)
    parser.AppendItem(four)
    parser.AppendItem(quit)
    menubar.Append(parser, '&Table Parsers')

    textRip = wx.Menu()
    section =wx.MenuItem(parser,1,'&Extract Text With Section Headings')
    textRip.AppendItem(section)
    menubar.Append(textRip, '&Text Rippers')

    dataHandling = wx.Menu()
    deHydrate =wx.MenuItem(dataHandling,1,'&Extract Data from Tables')
    dataHandling.AppendItem(deHydrate)
    menubar.Append(dataHandling, '&Data Extraction')        


    self.Bind(wx.EVT_MENU, self.OnQuit, id=2)

das ist, wo ich denke, ich bin klug ist, um eine Schaltfläche klicken, um eine Instanz zu erstellen, indem Sie mit

von SUBPANEL.

    self.Bind(wx.EVT_MENU, self.subPanel(None, -1, 'TEST'),id=1)

    self.SetMenuBar(menubar)

    self.Centre()
    self.Show(True)

   def OnQuit(self, event):
    self.Close()

class subPanel(wx.Frame):
    def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, id, 'directEDGAR Supplemental Tools', size=(450, 450))
    wx.Panel(self,-1)
    wx.StaticText(self,-1, "This is where I will describe\n the purpose of these tools",(100,10))


    getDirectory = wx.Button(panel, -1, "Get Directory Path", pos=(20,350))
    getDirectory.SetDefault()

    getTerm1 = wx.Button(panel, -1, "Get Search Term", pos=(20,400))
    getTerm1.SetDefault()

    #getDirectory.Bind(wx.EVT_BUTTON, getDirectory.OnClick, getDirectory.button)


    self.Centre()
    self.Show(True)




app = wx.App()
mainPanel(None, -1, '')
app.MainLoop()
War es hilfreich?

Lösung

Sie müssen einen Event-Handler in Ihrem binden Ausdruck

self.bind(wx.EVT_MENU, subPanel(None, -1, 'TEST'),id=1)

geändert werden muss, um:

self.bind(wx.EVT_MENU, <event handler>, <id of menu item>)

, wo Ihre Event-Handler auf das Ereignis reagiert und instanziiert das subpanel:

def OnMenuItem(self, evt): #don't forget the evt
    sp = SubPanel(self, wx.ID_ANY, 'TEST')
    #I assume you will add it to a sizer
    #if you aren't... you should
    test_sizer.Add(sp, 1, wx.EXPAND)
    #force the frame to refresh the sizers:
    self.Layout()

Alternativ können Sie die Blendenhalterung in Ihrem Rahmen des __init__ instanziiert und eine subpanel.Hide() nach der Instanzierung aufrufen und Ihre menuitem Ereignishandler dann und eine Show auf dem Panel subpanel.Show() rufen

Edit: Hier ist ein Code, der das tut, was ich denke, dass Sie fragen:

#!usr/bin/env python

import wx

class TestFrame(wx.Frame):
    def __init__(self, parent, *args, **kwargs):
        wx.Frame.__init__(self, parent, *args, **kwargs)
        framesizer = wx.BoxSizer(wx.VERTICAL)
        mainpanel = MainPanel(self, wx.ID_ANY)
        self.subpanel = SubPanel(self, wx.ID_ANY)
        self.subpanel.Hide()
        framesizer.Add(mainpanel, 1, wx.EXPAND)
        framesizer.Add(self.subpanel, 1, wx.EXPAND)
        self.SetSizerAndFit(framesizer)

class MainPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)
        panelsizer = wx.BoxSizer(wx.VERTICAL)
        but = wx.Button(self, wx.ID_ANY, "Add")
        self.Bind(wx.EVT_BUTTON, self.OnAdd, but)
        self.panel_shown = False
        panelsizer.Add(but, 0)
        self.SetSizer(panelsizer)

    def OnAdd(self, evt):
        if not self.panel_shown:
            self.GetParent().subpanel.Show()
            self.GetParent().Fit()
            self.GetParent().Layout()
            self.panel_shown = True
        else:
            self.GetParent().subpanel.Hide()
            self.GetParent().Fit()
            self.GetParent().Layout()
            self.panel_shown = False

class SubPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)
        spsizer = wx.BoxSizer(wx.VERTICAL)
        text = wx.StaticText(self, wx.ID_ANY, label='I am a subpanel')
        spsizer.Add(text, 1, wx.EXPAND)
        self.SetSizer(spsizer)

if __name__ == '__main__':
    app = wx.App()
    frame = TestFrame(None, wx.ID_ANY, "Test Frame")
    frame.Show()
    app.MainLoop()

Andere Tipps

Ich weiß nicht, wxWidgets, sondern auf das, was ich von Python wissen, ich vermute, dass Sie ändern müssen:

self.Bind(wx.EVT_MENU, self.subPanel(None, -1, 'TEST'),id=1)

zu:

self.Bind(wx.EVT_MENU, subPanel(None, -1, 'TEST'),id=1)

„SUBPANEL“ ist eine global definierte Klasse, kein Mitglied der „Selbst“ (das ein Mainpanel).

Edit: Ah, „Bind“ scheint eine Aktion auf eine Funktion zu binden, so müssen Sie es eine Funktion geben, die die andere Klasse erstellt. Versuche Folgendes. Es funktioniert immer noch nicht, aber zumindest stürzt jetzt während der SUBPANEL Schöpfung.

self.Bind(wx.EVT_MENU, lambda(x): subPanel(None, -1, 'TEST'),id=1)

Sie sollten die Schaltfläche Click-Ereignis, Griff und die Platte in Ihrem Tastenhandler erstellen (wie Sie bereits mit Ihrer OnQuit Methode tun).

Ich denke, der folgende Code im Grunde tut, was sind Sie nach -. Einen neuen Rahmen erstellt, wenn die Schaltfläche geklickt wird / Menüpunkt ausgewählt wird,

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, title="My Frame", num=1):

        self.num = num
        wx.Frame.__init__(self, parent, -1, title)
        panel = wx.Panel(self)

        button = wx.Button(panel, -1, "New Panel")
        button.SetPosition((15, 15))
        self.Bind(wx.EVT_BUTTON, self.OnNewPanel, button)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        # Now create a menu
        menubar = wx.MenuBar()
        self.SetMenuBar(menubar)

        # Panel menu
        panel_menu = wx.Menu()

        # The menu item
        menu_newpanel = wx.MenuItem(panel_menu,
                                    wx.NewId(),
                                    "&New Panel",
                                    "Creates a new panel",
                                    wx.ITEM_NORMAL)
        panel_menu.AppendItem(menu_newpanel)

        menubar.Append(panel_menu, "&Panels")
        # Bind the menu event
        self.Bind(wx.EVT_MENU, self.OnNewPanel, menu_newpanel)

    def OnNewPanel(self, event):
        panel = MyFrame(self, "Panel %s" % self.num, self.num+1)
        panel.Show()

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

def main():
    application = wx.PySimpleApp()
    frame = MyFrame(None)
    frame.Show()
    application.MainLoop()

if __name__ == "__main__":
    main()

Bearbeiten :. Code hinzugefügt diese aus einem Menü zu tun

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top