Почему мои классы диалоговых окон пишут друг другу? - PullRequest
2 голосов
/ 06 августа 2011

Я работаю над программой, которая будет использоваться в исследовании Time Motion. Временами пользователю может понадобиться создать и добавить новые объекты (Наблюдатель, Предмет, Клиника). Для этого я использовал модальное диалоговое окно (поскольку все данные связаны с субъектом, наблюдателем и клиникой).

Я создал общий класс для диалоговых окон, а затем просто создаю экземпляр этого класса для каждого диалогового окна. Однако, когда пользователь создает новую запись с одним классом, а затем с другим, ввод предыдущих классов создается снова, что приводит к дублированию в данных.

Я не совсем уверен, что происходит, и мне нужна помощь:

Вот мой общий класс диалогового окна:

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

Для полного просмотра кода вы можете посмотреть здесь . Примечание: не все комментарии правильно аннотированы, и есть другие файлы, как часть этого, и поэтому они не будут работать, но, надеюсь, дадут вам немного больше понимания того, что происходит

1 Ответ

4 голосов
/ 06 августа 2011

Вы храните ссылки на экземпляры NewDataDialog в self.newsubject, self.newobserver и self.newclinic.Это означает, что объекты продолжают существовать и ожидать события "mainpanel.SaveButton" даже после выхода из методов newsubject, newobserver и newclinic.После того, как вы откроете одно из диалоговых окон каждого типа, вокруг всегда будет три таких объекта, и каждое событие "mainpanel.SaveButton" заставит все три попытаться сохранить свои данные.

Если вы этого не сделалисохраните эти ссылки, тогда объекты будут , по-видимому , подвергаться сборке мусора, и подписки будут автоматически удалены.Если вам нужно сохранить ссылки, то вам следует организовать unsubscribe после ShowModal().

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()
...