Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我的对话框类会相互写入?_Python_Wxpython_Modal Dialog_Duplicates - Fatal编程技术网

Python 为什么我的对话框类会相互写入?

Python 为什么我的对话框类会相互写入?,python,wxpython,modal-dialog,duplicates,Python,Wxpython,Modal Dialog,Duplicates,我正在做一个程序,它将用于时间运动研究。有时,用户可能需要创建并添加新对象(观察者、受试者、诊所)。为了实现这一点,我使用了一个模态对话框(因为所有数据都与一个受试者、观察者和临床相关) 我已经为对话框创建了一个通用类,然后只为每个对话框创建了这个类的一个实例。但是,当用户使用一个类创建新条目,然后使用另一个类创建新条目时,会再次创建以前的类输入,从而导致数据重复 我不太清楚发生了什么,正在寻求帮助: 下面是我的常规对话框类: class NewDataDialog(wx.Dialog): de

我正在做一个程序,它将用于时间运动研究。有时,用户可能需要创建并添加新对象(观察者、受试者、诊所)。为了实现这一点,我使用了一个模态对话框(因为所有数据都与一个受试者、观察者和临床相关)

我已经为对话框创建了一个通用类,然后只为每个对话框创建了这个类的一个实例。但是,当用户使用一个类创建新条目,然后使用另一个类创建新条目时,会再次创建以前的类输入,从而导致数据重复

我不太清楚发生了什么,正在寻求帮助:

下面是我的常规对话框类:

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


有关代码的完整视图,您可以查看。注意:并非所有注释都被正确注释,并且还有其他文件作为注释的一部分,因此不会运行,但希望能让您更深入地了解发生了什么事情

您正在
self.newsubject
中存储对
NewDataDialog
实例的引用,
self.newobserver
self.newclinic
。这意味着即使在
newsubject
newobserver
newclinic
方法退出后,对象仍将继续存在,并侦听
“mainpanel.SaveButton”
事件。打开每种对话框中的一个后,总会有三个这样的对象挂起,每个
“mainpanel.SaveButton”
事件都会导致这三个对象尝试保存数据

如果没有存储这些引用,那么对象将被垃圾收集,订阅将自动删除。如果确实需要存储引用,则应在
showmodel()
之后安排
unsubscribe


真实的对象是如何与代码连接的?看不到任何用于创建新对象的代码,仅限于表单。或者我错过了什么?什么是
pub
?它看起来可能是一个全局对象,它积累了对您创建的每个
NewDataDialog
对象的
savebutton
方法的引用。如果有什么原因导致这些累积的引用稍后被调用,这将解释重复的数据。我想你需要在某个时间取消订阅point@slowdog它用于在类和文件之间移动数据。快告诉我!尽管我指的是你的评论,但你值得表扬
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()