#!/usr/bin/python
from tkinter import *
from tkinter.ttk import *
from socket import *
import select
class window(Frame):
def __init__(self, parent, name, networker):
self.networker = networker
self.name=name
self.count=0
self.scrollx=900
self.scrolly=0
self.messageStr=""
Frame.__init__(self, parent)
self.parent = parent
self.parent.title("Chat")
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand="yes")
self.lfone = Frame(self)
self.messageCanvas = Canvas(self.lfone, relief=RAISED, height=0, width=0, scrollregion=(0,0,self.scrollx,self.scrolly))
self.myentry = Entry(self)
self.sendbutton = Button(self, text="Send", command=self.sendbuttoncommand)
self.scrollbar = Scrollbar(self.lfone)
self.lfone.pack(fill=BOTH, expand="yes")
self.myentry.pack(side=LEFT, fill=BOTH, expand="yes", padx=5)
self.messageCanvas.pack(side=LEFT, fill=BOTH, expand="yes", padx=5, pady=5)
self.sendbutton.pack(side=RIGHT, padx=5)
self.scrollbar.pack(side=RIGHT, fill=Y, pady=5)
self.messageCanvas.configure(yscrollcommand=self.scrollbar.set)
self.scrollbar.config(command=self.messageCanvas.yview)
self.doListen()
def sendbuttoncommand(self):
self.count=self.count+20
self.scrolly=self.scrolly+20
str = (self.name + ": " + self.myentry.get())
b = bytearray(str, "utf-8")
self.messageCanvas.create_text(5, self.count, anchor=SW, text=(self.name + ": " + self.myentry.get()))
self.messageCanvas.config(scrollregion=(0,0,self.scrollx, self.scrolly))
self.networker.myhost.send(b)
def post(self, str):
self.count=self.count + 20
self.scrolly=self.scrolly+20
self.messageCanvas.create_text(5, self.count, anchor=SW, text=str)
self.messageCanvas.config(scrollregion=(0,0,self.scrollx, self.scrolly))
def doListen(self):
str = self.networker.listen()
if str != "":
self.post(str)
self.after(128, self.doListen)
class splash(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent=parent
parent.title("INIT")
self.splashed=False
self.initgui()
def initgui(self):
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=YES)
self.label = Label(self, text="Choose a name")
self.entry = Entry(self)
self.button = Button(self, text="Submit", command=lambda: self.doSplash())
self.ipentry = Entry(self)
self.iplabel = Label(self, text="IP addr to connect to:")
self.label.pack(side=TOP, pady=5)
self.entry.pack(fill=X, expand=YES, padx=5)
self.iplabel.pack()
self.ipentry.pack(fill=X, padx=5)
self.button.pack(side=BOTTOM, pady=5)
def doSplash(self):
self.name=self.entry.get()
#TODO: exception handling for ip addr
self.addr=self.ipentry.get()
self.splashed=True
self.parent.destroy()
class networker():
def __init__(self):
self.myhost = socket(AF_INET, SOCK_STREAM)
self.myclient = socket(AF_INET, SOCK_STREAM)
self.host=gethostname()
self.port=2007
self.myhost.bind((self.host,self.port))
self.myhost.listen(5)
self.clientConnected=False
self.myhost.setblocking(0)
def connectToHost(self, hostname):
self.myclient.connect((hostname,self.port))
def getClient(self):
self.client, self.addr = self.myhost.accept()
print("Got a connection from %s" % str(self.addr))
self.clientConnected=True
def listen(self):
ready = select.select([self.myclient], [], [], 1)
if ready == 0:
str = self.myclient.recv(1024)
return str
return ""
def main():
myN = networker()
splashRoot = Tk()
splashApp=splash(splashRoot)
splashRoot.mainloop()
myN.connectToHost(splashApp.addr)
myN.getClient()
if splashApp.splashed:
root = Tk()
root.geometry("900x600+300+300")
app=window(root, splashApp.name, myN)
root.mainloop()
if __name__ == '__main__':
main()所以这应该是一个简单的聊天程序。对不起,所有的代码,但我担心这是没有意义的,如果我剪了它。
想法: networker对象连接到输入的IP地址(在我的测试用例中,我自己的addr)并报告它的成功。窗口接受一个networker对象,并在doListen()中调用它的listen()方法。doListen()使用after进行多任务侦听和维护gui。sendbuttoncommand()应该在输入时将消息发送到客户端和发送方的屏幕,但它是错误的来源。
大多数情况下,它是有效的,并且声称连接成功。但是,当我尝试使用window.sendbuttoncommand()时,我会收到一个坏管道错误。总的来说,我对python和网络编程都很陌生,我不知道造成这种情况的原因是什么。我的一些想法:
任何建议/帮助/洞察力都是非常感谢的。
发布于 2015-05-18 04:12:19
这个问题的答案不是做我想做的事,而是用一些扭曲的东西代替。没有必要重新发明轮子
https://stackoverflow.com/questions/29888057
复制相似问题