2015-04-27 103 views
2

我正在研究可以将输入从一个客户端写入多客户端的多客户端/服务器聊天应用程序。对于客户端来说,它运行良好,但是对于服务器端,我想添加一个可以在客户端自己的屏幕上输出输入的部分。而当我做这个工作,我遇到的初始化()的问题恰恰3个arguements(2给出)符合“self.app =程序”找不到TypeError:__init __()需要3个参数(给出2个)

这里是我的代码

import kivy 
from kivy.app import App 
from kivy.uix.label import Label 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button 
from kivy.support import install_twisted_reactor 
install_twisted_reactor() 
from twisted.internet import reactor 
from twisted.internet.protocol import Protocol, Factory 

class MultiClientEcho(Protocol): 

    def __init__(self, factory, app): 
     self.factory = factory 
     self.app = app 

    def connectionMade(self): 
     self.factory.clients.append(self) 

    def dataReceived(self, data): 
     for client in self.factory.clients: 
      addtolog = self.factory.app.handle_message(data) 
      if addtolog: 
       client.transport.write(data) 

    def connectionLost(self,reason): 
     self.factory.clients.remove(self) 

class MultiClientEchoFactory(Factory): 
    protocol = MultiClientEcho 
    def __init__(self): 
     self.clients = [] 

    def buildProtocol(self, addr): 
      return MultiClientEcho(self) 


class ServerApp(App): 
    def build(self): 
     self.label = Label(text="server started\n") 
     reactor.listenTCP(8000, MultiClientEchoFactory()) 
     return self.label 

    def handle_message(self, msg): 
     self.label.text = "received: %s\n" % msg 
     return msg 


if __name__ == '__main__': 
    ServerApp().run() 

有趣的是,我只是从这个网站的源代码中进行调整:http://kivy.org/docs/guide/other-frameworks.html,它自己的工作也很好,但是一旦我将协议更改为MultiClientEcho,它立即导致这种类型的错误。我怎样才能解决这个问题?

回答

2

看那__init__定义MultiClientEchoFactory

def __init__(self, factory, app): 

这需要三个参数的功能(否则它会抛出一个错误)。

你叫这条线的位置:

return MultiClientEcho(self) 

现在,__init__self将获得自动为您的MultiClientEcho这个实例定义。 factory将被定义为您的实例MultiClientEchoFactory。但是,您尚未传入app的参数,因此python无法继续。

你可能想要做的是在build功能通过您的ServerApp实例进入MultiClientEchoFactory构造:

reactor.listenTCP(8000, MultiClientEchoFactory(self)) 

改变出厂为:

def __init__(self, app): 
    self.app = app 
    self.clients = [] 

def buildProtocol(self, addr): 
     return MultiClientEcho(self, self.app) 

这将摆脱现在您将提供第三个参数app

+0

的伟大工程,太感谢你了! –

0

错误信息似乎很清楚:MultiClientEcho__init__方法需要三个参数(工厂和应用程序以及自动自我),但你只有通过自我和工厂当你在buildProtocol方法实例化。它应该从哪里得到app

2

你调用MultiClientEchoFactoryMultiClientEcho(self)只有一个参数,factory

def buildProtocol(self, addr): 
      return MultiClientEcho(self) 

你应该尝试像

class MultiClientEchoFactory(Factory): 
    protocol = MultiClientEcho 
    def __init__(self,app): 
     self.clients = [] 
     self.app=app 

    def buildProtocol(self, addr): 
      return MultiClientEcho(self,app) 


class ServerApp(App): 
    def build(self): 
     self.label = Label(text="server started\n") 
     reactor.listenTCP(8000, MultiClientEchoFactory(self)) 
     return self.label 

    def handle_message(self, msg): 
     self.label.text = "received: %s\n" % msg 
     return msg 


if __name__ == '__main__': 
    ServerApp().run() 
相关问题