Проблема с wxReactor - PullRequest
       5

Проблема с wxReactor

1 голос
/ 16 ноября 2010

Я занимаюсь разработкой программы, которая использует Twisted и wxReactor.Каждый раз, когда я пытаюсь выйти из приложения, оно зависает, и мне приходится принудительно выходить из него.В моем событии wxPython OnClose () вызывается реактор.stop (), который, насколько мне известно, должен решить эту проблему.В поисках ответа я наткнулся на этот билет: www.twistedmatrix.com/trac/ticket/3948.
Я попробовал патч, указанный на странице, но безуспешно.Я занимаюсь этой проблемой уже 2 недели и очень отчаялся:).

Чтобы дать вам представление об этом проекте: это бесплатный клиент, использующий сокеты для подключения к серверу многопользовательской игры(в настоящее время играет Монополию и Уно).Если вы запустите его, вы сразу заметите, что нет графики.Это потому, что этот клиент обеспечивает звуковую обратную связь только через синтез речи и звуковые эффекты.Целевая аудитория этого проекта - слабовидящие геймеры.

Чтобы проверить проблему, запустите python rsg.py (который можно найти в папке src. Если вам нужно знать, я использую Python 2.6.5).В терминале вы увидите выходные данные, которые выводит программа (в основном это то, что сервер отправляет нашему клиенту).Когда вы увидите строку «Соединение установлено» (которая должна быть напечатана очень скоро после запуска), попробуйте закрыть программу (нажав «Х»).Клиент зависнет на несколько секунд, а затем вам придется принудительно завершить работу приложения (в 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 ]

1 голос
/ 19 января 2011

Это будет работать для вас:

def OnClose(self, evt):
    # ugly hack until wxreactor is patched:
    reactor._stopping = True
    reactor.callFromThread(_threadedselect.ThreadedSelectReactor.stop, reactor)
0 голосов
/ 05 января 2011

У меня была такая же проблема в одном из моих проектов.Мне просто нужно удалить следующий код:

  1. sys.exit () из метода OnClose ().

Когда вы используете витую, реактор управляет вашим приложением.Остановив реактор, вы также остановите все приложение.Проблема может быть вызвана исключением, вызванным из sys.exit () (если это так, я не уверен), так как реактор перехватывает все исключения и сообщает в консоль.

Просто помните, когда вы 'При использовании витой или другой подобной среды, вы должны думать немного иначе ( Инверсия управления ).Кроме того, я рекомендую прочитать этот великолепный учебник по Асинхронное программирование и витая .

  1. app.MainLoop ()

Реактор должен вызывать MainLoop() внутри метода run.В вашем коде вы запускаете два основных цикла, и вам нужно дважды закрыть главное окно, чтобы выйти.

...