2011-08-05 9 views
2

私は、Time Motionスタディで使用される予定のプログラムに取り組んでいます。ユーザーが新しいオブジェクト(Observer、Subject、Clinic)を追加しなければならない場合があります。これを達成するために、モーダルダイアログボックスを使用しました(すべてのデータはサブジェクト、オブザーバー、およびクリニックに関連付けられているため)。なぜ私のダイアログボックスクラスはお互いに書き込みますか?

私はダイアログボックスの一般クラスを作成してから、各クラスのダイアログボックスに対してこのクラスのインスタンスを作成しました。ただし、ユーザーがあるクラスで新しいエントリを作成し、次に別のクラスに新しいエントリを作成すると、以前のクラス入力が再び作成され、データが重複して生成されます。

私は上に行くといくつかの助けを探しているかを正確にはわからない:

ここに私の一般的なダイアログボックスクラスです:

class NewDataDialog(wx.Dialog): 
def __init__(self, parent, id, title, databoxes, pubsubmessage): 
    wx.Dialog.__init__(self,parent,id, title) 

    self.databoxes = databoxes 
    self.pubsubmessage = pubsubmessage 
    # MainSizer Creation 
    self.MainSizer = wx.BoxSizer(wx.VERTICAL) 

    # Top Label Creation and addition to Main Sizer 
    self.TopLbl = wx.StaticText(self, -1, "Create a " + title) 
    self.TopLbl.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)) 
    self.MainSizer.Add(self.TopLbl, 0, wx.ALL|wx.ALIGN_CENTER, 5) 

    self.SubSizer = wx.BoxSizer(wx.HORIZONTAL) 

    # Labels 
    self.LblSizer = wx.BoxSizer(wx.VERTICAL) 

    for lbl in databoxes: 
     self.lbl = wx.StaticText(self, -1, lbl+":") 
     self.LblSizer.Add(self.lbl, 0, wx.ALL|wx.ALIGN_LEFT, 5) 


    self.SubSizer.Add(self.LblSizer, 0, wx.ALL|wx.ALIGN_LEFT, 5) 

    # Boxes 
    self.InputSizer = wx.BoxSizer(wx.VERTICAL) 

    for lbl in databoxes: 
     self.box = wx.TextCtrl(self, -1, style=wx.ALIGN_LEFT) 
     self.InputSizer.Add(self.box, 0, wx.ALL, 1) 

    self.SubSizer.Add(self.InputSizer, 0, wx.ALL|wx.ALIGN_LEFT, 5) 
    self.MainSizer.Add(self.SubSizer, 0, wx.ALL|wx.ALIGN_CENTER, 5) 

    # Save and Cancel Buttons 
    self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL) 
    self.saveButton = SaveButton(self, 'Save') 
    self.cancelButton = CancelButton(self, 'Cancel') 
    self.buttonSizer.Add(self.saveButton, 0, wx.ALL|wx.ALIGN_CENTER, 5) 
    self.buttonSizer.Add(self.cancelButton, 0, wx.ALL|wx.ALIGN_CENTER, 5) 

    self.MainSizer.Add(self.buttonSizer, 0, wx.ALL|wx.ALIGN_CENTER, 5) 
    self.SetSizerAndFit(self.MainSizer) 

    pub.subscribe(self.cancelbutton, "mainpanel.CancelButton") 
    pub.subscribe(self.savebutton, "mainpanel.SaveButton") 

def cancelbutton(self, message): 

    self.Close() 


def savebutton(self, message): 

    results = [] 

    for lbl in self.databoxes: 
     results.append(self.box.GetValue()) 

    pub.sendMessage(self.pubsubmessage, results) 
    self.Close() 

class CancelButton(wx.Panel): 
    def __init__(self, parent, title): 

     wx.Panel.__init__(self, parent) 

     self.dialogbutton = wx.Button(self, -1, title) 

     self.Bind(wx.EVT_BUTTON, self.OnButtonActivate, self.dialogbutton) 


    def OnButtonActivate(self, event): 

     pub.sendMessage("mainpanel.CancelButton", "") 


class SaveButton(CancelButton): 

    def OnButtonActivate(self, event): 

     pub.sendMessage("mainpanel.SaveButton", "") 

そしてここでは、ダイアログボックスの各インスタンスの作成です:

def newsubject(self, message): 

    titles = ["Full Name", "Initials", "Job Title"] 
    self.newsubject = NewDataDialog(self, 0, 'New Subject', titles, "MainPanel.NewSubjectDialog.Save") 
    self.newsubject.ShowModal() 

def newobserver(self, message): 

    titles = ["Full Name", "Initials"] 
    self.newobserver = NewDataDialog(self, 1, 'New Observer', titles, "MainPanel.NewObserverDialog.Save") 
    self.newobserver.ShowModal() 

def newclinic(self, message): 

    titles = ["Clinic Name","Location","Initials"] 
    self.newclinic = NewDataDialog(self, 2, 'New Clinic', titles, "MainPanel.NewClinicDialog.Save") 
    self.newclinic.ShowModal() 

ここでは、ユーザーが希望する動作のラベルが付けられたボタンを選択すると、これらのボタンがそれぞれ呼び出されます。私。 "新しいオブザーバを作成"機能を実行しますnewobserver

hereのコードを完全に見ることができます。 注:すべてのコメントに正しく注釈が付けられているわけではありません。そのため、他のファイルもありますので実行されません。

+0

実際のオブジェクトはどのようにこのコードに結びついていますか?新しいオブジェクトを作成するためのコードは表示されません。または私は何かを逃したのですか? –

+0

「パブ」とは何ですか?作成するすべての 'NewDataDialog'オブジェクトの' savebutton'メソッドへの参照を蓄積するグローバルオブジェクトであるようです。蓄積された参照が後で呼び出されるようなものがあると、重複したデータが説明されます。あなたはある時点で 'unsubscribe'が必要だと思います。 – slowdog

+0

@slowdogクラスとファイルの間でデータを移動するのに使われる[pubsub](http://pubsub.sourceforge.net/)です。 – KronoS

答えて

4

参考資料を保存していますNewDataDialogのインスタンスはself.newsubjectself.newobserverおよびself.newclinicです。これは、オブジェクトが存在し続け、newsubject,newobserver、およびnewclinicメソッドが終了した後でも、イベントをリスンすることを意味します。いったん各種類のダイアログボックスを開くと、そのようなオブジェクトが3つあり、それぞれ"mainpanel.SaveButton"イベントでは、3つのすべてがデータを保存しようとします。

これらの参照を保存しなかった場合、オブジェクトはapparentlyにガベージコレクトされ、サブスクリプションは自動的に削除されます。参照を保存する必要がある場合は、ShowModal()の後にunsubscribeが発生するように手配してください。

def cancelbutton(self, message): 

    pub.unsubscribe(self.savebutton, "mainpanel.SaveButton") 
    pub.unsubscribe(self.cancelbutton, "mainpanel.CancelButton") 
    self.Close() 


def savebutton(self, message): 

    results = [] 

    for lbl in self.databoxes: 
     results.append(self.box.GetValue()) 

    pub.sendMessage(self.pubsubmessage, results) 
    pub.unsubscribe(self.savebutton, "mainpanel.SaveButton") 
    pub.unsubscribe(self.cancelbutton, "mainpanel.CancelButton") 
    self.Close() 
+0

私にそれを打つ!私はあなたのコメントをとにかく言及していましたが、あなたは信用に値する –