wxReactor问题

时间:2010-11-16 00:17:44

标签: python wxpython twisted

我正在开发一个使用Twisted和wxReactor的程序。每当我尝试退出应用程序时,它都会挂起,我必须强行退出它。我的wxPython OnClose()事件确实调用了reactor.stop(),据我所知应该解决这个问题。在我寻求答案时,我遇到了这张票:www.twistedmatrix.com/trac/ticket/3948。
我已经尝试过页面上列出的补丁,没有运气。我已经在这个问题上待了两个星期了,而且非常绝望:)。

为您提供有关此项目的所有背景信息:它是一个免费软件客户端,它使用套接字连接到多人游戏服务器(目前播放Monopoly和Uno)。如果你运行它,你会立即注意到没有图形。这是因为该客户端仅通过语音合成和声音效果提供音频反馈。该项目的目标受众是视障游戏玩家。

要测试此问题,请运行python rsg.py(可以在src文件夹中找到。如果您需要知道,我使用的是Python 2.6.5)。在终端中,您将看到程序生成的输出(主要是服务器发送给客户端的输出)。一旦看到“Connection Made”行(应在运行后很快打印),请尝试关闭程序(通过单击X)。客户端将挂起几秒钟,然后您将需要强制退出应用程序(在Ubuntu上,它会询问我是否要强制退出应用程序)。

我确实知道它为什么不能正常退出。当我通过gdb运行它时,两个线程没有退出。奇怪的是,如果服务器关闭连接,那么我退出程序,它会正常工作。

我非常感谢所有的帮助。提前谢谢。

修改 因为我被要求提供我的问题的基本演示,所以它是:

import wx
import sys
from twisted.internet import wxreactor
wxreactor.install()

# import t.i.reactor only after installing wxreactor:
from twisted.internet import reactor
from twisted.protocols.basic import LineReceiver
from twisted.internet.protocol import ClientFactory
class ZGPClient(LineReceiver):
    """Our client object."""
    def lineReceived(self, datavar):
         "As soon as any data is received"
         print datavar

class EchoFactory(ClientFactory):
    protocol =  ZGPClient
    def startedConnecting(self, connector):
        global conn
        conn = connector
        print 'Started to connect.'

    def sendData(self, data=""):
      conn.transport.write(data.encode("ascii", "ignore") + "\n")

class main_window(wx.Frame):
 def __init__(self, parent, id, title):
  super(main_window, self).__init__(parent, id, title, style=wx.DEFAULT_FRAME_STYLE)
  self.Bind(wx.EVT_CLOSE, self.OnClose)
  self.Show(True)

 def OnClose(self, event):
   reactor.stop()
   sys.exit()

if __name__ == "__main__":
  app = wx.App()
  frame = main_window(None, wx.ID_ANY, "RS Games Client - No Game")
  reactor.registerWxApp(app)
  sockObj = EchoFactory()
  reactor.connectTCP("rsgamesmonserver.webhop.org", 3555, sockObj)
  reactor.run()
  app.MainLoop()

2 个答案:

答案 0 :(得分:1)

这对你有用:

def OnClose(self, evt):
    # ugly hack until wxreactor is patched:
    reactor._stopping = True
    reactor.callFromThread(_threadedselect.ThreadedSelectReactor.stop, reactor)

答案 1 :(得分:0)

我的一个项目遇到了同样的问题。 我只需要删除以下代码:

    来自OnClose()方法的
  1. sys.exit()。
  2. 当您使用扭曲时,反应堆正在驱动您的应用程序。通过停止反应堆,您也可以停止整个应用程序。问题可能是由sys.exit()引发的异常引起的(如果确实如此,我不确定),因为reactor正在捕获所有异常并向控制台报告。

    请记住,当你使用扭曲或其他类似的框架时,你必须以一种不同的方式思考(Inversion of control)。另外,我建议您在Asynchronous Programming and Twisted上阅读这个精彩的教程系列。

    1. app.MainLoop()
    2. 反应器必须在其run方法中调用MainLoop()。在您的代码中,您将启动两个主循环,并且您需要关闭主窗口两次才能退出。

相关问题