2015-06-23 73 views
0

我正在嘗試構建一個基本的消息傳遞系統,但我在這個過程中遇到了一個主要障礙。如果沒有響應,我無法關閉窗口,我必須在任務管理器中關閉它。從我在線閱讀的內容來看,聽起來好像我需要關閉sys.exit(0)以退出所有線程和連接。我一直被困在這個問題上好幾天,所以我真的很感激爲什麼它不起作用的答案和解釋!問題的關鍵在close_window()函數中。它可以運行,只要你有一個接受連接的基本服務器。謝謝!爲什麼我的wxFrame不能正確關閉?

import wx 
import socket 
import threading 
import sys 

class oranges(wx.Frame): 
    def __init__(self,parent,id): 

     ##Unimportant stuff 
     wx.Frame.__init__(self,parent,id," Retro Message",size=(500,500)) 
     self.frame=wx.Panel(self) 
     self.input_box=wx.TextCtrl(self.frame, -1,pos=(15,350),size=(455,120),style=wx.NO_BORDER| wx.TE_MULTILINE) 
     self.messaging_box=wx.TextCtrl(self.frame, -1,pos=(15,15),size=(455,285),style=wx.NO_BORDER | wx.TE_MULTILINE|wx.TE_READONLY) 
     send_button=wx.Button(self.frame,label="Send",pos=(350,315),size=(75,40)) 
     self.Bind(wx.EVT_BUTTON, self.sender,send_button) 
     self.Bind(wx.EVT_CLOSE, self.close_window) 
     self.counter = 1 
     self.socket_connect = socket.socket() 
     self.setup() 

    def sender(self,event): 
     self.socket_connect.send(self.input_box.GetValue()) 
     self.input_box.Clear() 
     self.Refresh() 

     ##Important stuff 
    def close_window(self,event): #This is the function in question# 
     self.counter = 0 
     self.socket_connect.shutdown(socket.SHUT_RDWR) 
     sys.exit(0) 
    def setup(self): 
     self.ip_enter = wx.TextEntryDialog(None, "Enter in the IP:", "Setup", "192.168.1.1") 
     if self.ip_enter.ShowModal() ==wx.ID_OK: 
      self.offical_ip = self.ip_enter.GetValue() 
      try: 
       self.socket_connect.connect((self.offical_ip,5003)) 
       self.username = "false" #Tells the server just to give the user a IP username 
       self.Thread1 = threading.Thread(target = self.listening_connect) 
       self.Thread1.start() 
      except socket.error: 
       self.error_connect() 
     else: 
      sys.exit(0) 

    def listening_connect(self): 
     self.socket_connect.send(self.username) 
     while self.counter != 0: 
      data = self.socket_connect.recv(1024) 
      self.messaging_box.AppendText(data) 
      self.Refresh() 
      if not data: 
       break 
     self.socket_connect.close()   
    def error_connect(self): 
     pop_ups = wx.MessageDialog(None, "Failed to Connect to Server!", 'Error', wx.OK) 
     pop_ups.ShowModal() 
     self.setup() 

if __name__=="__main__": 
    app=wx.App(False) 
    window=oranges(parent=None,id=-1) 
    window.Show() 
    app.MainLoop() 

這是一個基本的服務器程序,應該使用它(我無法測試它,但它是非常相似的真實的)

import socket 

HOST = '192.168.1.1' 
PORT=5003 
s = socket.socket() 
s.bind((HOST, PORT)) 
s.listen(1) 
c,addr = s.accept() 
while True: 
    data = c.recv(1024) 
    if not data: 
     break 
c.close() 

回答

1

你需要等待線程結束。否則,它可能會使腳本掛起。爲什麼?那麼線程與GUI線程是分開的,所以它不會因爲關閉了你的wxPython應用程序而被殺死。這裏是我會推薦的:

def close_window(self, event): 
    self.Thread1.join() 
    self.Destroy() 

這使得腳本等待線程在關閉應用程序之前完成。如果您希望框架消失,則應在join之前致電self.Hide()。另一種方法是在你的線程中放入一些邏輯,在那裏你可以發送一條消息告訴它應用程序正在關閉,所以線程需要中止。

你或許應該看看下面的堆棧答案:

+0

這個問題似乎是在線程本身與while循環。即使我將'self.counter'變量設置爲0,while循環也不會退出,可能是因爲'self.socket_connect.recv(1024)'行。有任何想法嗎?感謝您的迴應! – user3818089