我关闭窗口时的Python PyDeadObjectError

时间:2014-05-01 20:30:19

标签: python wxpython

这是我的代码(不是全部因为它太长了)

class TestApp(wx.Frame):

def __init__(self,parent,id,title):
    """

    """
    print "Inside __init__" ## DEBUG
    wx.Frame.__init__(self,parent,id,title, size = (600,550),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)

    self.E = Errors()

    self.Bind(wx.EVT_CLOSE, self.close_main_window)

    self.is_running_flag0 = True
    self.is_connected_flag1 = False
    self.is_server_flag2 = False

    self.child_window_style = wx.DEFAULT_FRAME_STYLE|wx.STAY_ON_TOP ^ wx.RESIZE_BORDER
    self.error_window_style = wx.OK|wx.ICON_HAND|wx.STAY_ON_TOP

    self.create_gui()

    self.Show()

def create_gui(self):
    """

    """
    print "Inside create_gui" ## DEBUG
    self.panel = wx.Panel(self, id = -1)

    loc = wx.IconLocation('chat.ico', 0)
    self.SetIcon(wx.IconFromLocation(loc))

    self.main_txt = wx.TextCtrl(self.panel, id = -1, value="", pos=(5,10), size=(585,300), style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2)

    self.input_txt = wx.TextCtrl(self.panel, id = -1, value="", pos=(5,320), size=(385,150), style=wx.TE_MULTILINE)
    self.input_txt.SetMaxLength(512)
    self.input_txt.SetFocus()

    send_button = wx.Button(self.panel,label = "Send", pos=(400,320))
    self.Bind(wx.EVT_BUTTON, lambda event: self.get_text_input(), send_button)

    self.create_menu_bar()

def create_menu_bar(self):
    """

    """
    print "Inside create_menu_bar" ## DEBUG
    status_bar = self.CreateStatusBar()

    menu_bar = wx.MenuBar()
    file_menu = wx.Menu()
    option_menu = wx.Menu()
    about_menu = wx.Menu()

    connect_to_item = file_menu.Append(11, "&Connect to...", "Connect to someone")
    self.Bind(wx.EVT_MENU, self.connect_to_window, connect_to_item)
    open_connection_item = file_menu.Append(12, "&Open connection", "Start receiving incomming connections")
    self.Bind(wx.EVT_MENU, self.open_connection_window, open_connection_item)
    disconnect_item = file_menu.Append(13, "&Disconnect", "Disconnect")
    #self.Bind(wx.EVT_MENU, self.disconnect, disconnect_item)
    close_item = file_menu.Append(wx.ID_EXIT, "&Close", "Close the program")
    self.Bind(wx.EVT_MENU, self.close_main_window, close_item)
    settings_item = option_menu.Append(21, "&Settings", "Change settings")
    about_item = about_menu.Append(31, "&About", "About the release")

    menu_bar.Append(file_menu, "File")
    menu_bar.Append(option_menu, "Options")
    menu_bar.Append(about_menu, "About")

    self.SetMenuBar(menu_bar)

[...]

  def data_flow_thread(self):
        """
        NoType -> NoType
        This is the thread wich will start receiving the data after the connection is complete.
        """
        print "inside start_data_flow_thread",self.is_server_flag2 ## DEBUG
        while self.is_running_flag0 == True:
            time.sleep(0.1)
            print 0
            if self.is_server_flag2 == True:
                try:
                    msg = self.conn.recv(512)
                except socket.error, e:
                    sys.exit()
            else:
                try:
                    msg = self.client_s.recv(512)
                except socket.error, e:
                    sys.exit()
            if msg == "SPECIAL_MSG_DISCONECTED_70":
                self.disconnect()
            else:
                self.print_to_screen(msg)

        sys.exit()

    def disconnect(self):
        """
        NoType -> NoType
        This will just stop the connection if there is one.
        """
        print "inside disconnect" ## DEBUG

        try:
            print 1
            self.t3.exit()
        except:
            pass
        time.sleep(0.05)
        try:
            print 2
            self.client_s.send("SPECIAL_MSG_DISCONECTED_70")
            self.client_s.close()
        except:
            try:
                print 3
                self.conn.send("SPECIAL_MSG_DISCONECTED_70")
                self.conn.close()
                self.server_s.close()
            except:
                pass
        self.is_connected_flag1 = False

    def close_main_window(self, event):
        """

        """
        print "Inside close_window" ## DEBUG
        self.is_running_flag0 = False
        time.sleep(0.05)
        self.disconnect()
        print 4
        self.Destroy()

,这是错误消息

    Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 551, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Users\angelo\Documents\books n studies\Projects - Jump starts\chat\Si
ngle node chat resources\single node chat v2.2.1\single node chat v2.2.1u.py", l
ine 197, in data_flow_thread
    self.disconnect()
  File "C:\Python27\lib\site-packages\wx-3.0-msw\wx\_core.py", line 16712, in __
getattr__
    raise PyDeadObjectError(self.attrStr % self._name)
PyDeadObjectError: The C++ part of the TestApp object has been deleted, attribut
e access no longer allowed.

每次尝试将其关闭时都会发生这种情况。完全相同的代码与TKinter完全正常,但由于某种原因,我无法用WX克服它。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

看起来您正在退出线程内部错误的应用程序。您应该向wxPython GUI发送消息,告诉它存在问题。您可以向用户显示错误消息,或者只是在该点退出脚本。除非使用线程安全的方法,例如wx.CallAfter或wx.PostEvent,否则不能从GUI调用wxPython中的任何内容。

我会使用其中一个告诉您的GUI需要退出。我写了一个小教程,展示了如何使用wxPython和你可以在这里查看的线程: