Skip to content
Permalink
 
 
Cannot retrieve contributors at this time
import socket
import threading
import json # json.dumps(some)打包 json.loads(some)解包
import tkinter
import tkinter.messagebox
from tkinter.scrolledtext import ScrolledText # 导入多行文本框用到的包
import time
import requests
from tkinter import filedialog
import vachat
import os
from time import sleep
from PIL import ImageGrab
from netifaces import interfaces, ifaddresses, AF_INET6
IP = ''
PORT = ''
user = ''
listbox1 = '' # 用于显示在线用户的列表框
ii = 0 # 用于判断是开还是关闭列表框
users = [] # 在线用户列表
chat = '------Group chat-------' # 聊天对象, 默认为群聊
# 登陆窗口
root1 = tkinter.Tk()
root1.title('Log in')
root1['height'] = 110
root1['width'] = 270
root1.resizable(0, 0) # 限制窗口大小
IP1 = tkinter.StringVar()
IP1.set('127.0.0.1:50007') # 默认显示的ip和端口
User = tkinter.StringVar()
User.set('')
# 服务器标签
labelIP = tkinter.Label(root1, text='Server address')
labelIP.place(x=20, y=10, width=100, height=20)
entryIP = tkinter.Entry(root1, width=80, textvariable=IP1)
entryIP.place(x=120, y=10, width=130, height=20)
# 用户名标签
labelUser = tkinter.Label(root1, text='Username')
labelUser.place(x=30, y=40, width=80, height=20)
entryUser = tkinter.Entry(root1, width=80, textvariable=User)
entryUser.place(x=120, y=40, width=130, height=20)
# 登录按钮
def login(*args):
global IP, PORT, user
IP, PORT = entryIP.get().split(':') # 获取IP和端口号
PORT = int(PORT) # 端口号需要为int类型
user = entryUser.get()
if not user:
tkinter.messagebox.showerror('Name type error', message='Username Empty!')
else:
root1.destroy() # 关闭窗口
root1.bind('<Return>', login) # 回车绑定登录功能
but = tkinter.Button(root1, text='Log in', command=login)
but.place(x=100, y=70, width=70, height=30)
root1.mainloop()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IP, PORT))
if user:
s.send(user.encode()) # 发送用户名
else:
s.send('no'.encode()) # 没有输入用户名则标记no
# 如果没有用户名则将ip和端口号设置为用户名
addr = s.getsockname() # 获取客户端ip和端口号
addr = addr[0] + ':' + str(addr[1])
if user == '':
user = addr
# 聊天窗口
# 创建图形界面
root = tkinter.Tk()
root.title(user) # 窗口命名为用户名
root['height'] = 400
root['width'] = 580
root.resizable(0, 0) # 限制窗口大小
# 创建多行文本框
listbox = ScrolledText(root)
listbox.place(x=5, y=0, width=570, height=320)
# 文本框使用的字体颜色
listbox.tag_config('red', foreground='red')
listbox.tag_config('blue', foreground='blue')
listbox.tag_config('green', foreground='green')
listbox.tag_config('pink', foreground='pink')
listbox.insert(tkinter.END, 'Welcome to the chat room!', 'blue')
# 表情功能代码部分
# 四个按钮, 使用全局变量, 方便创建和销毁
b1 = ''
b2 = ''
b3 = ''
b4 = ''
# 将图片打开存入变量中
p1 = tkinter.PhotoImage(file='./emoji/facepalm.png')
p2 = tkinter.PhotoImage(file='./emoji/smirk.png')
p3 = tkinter.PhotoImage(file='./emoji/concerned.png')
p4 = tkinter.PhotoImage(file='./emoji/smart.png')
# 用字典将标记与表情图片一一对应, 用于后面接收标记判断表情贴图
dic = {'aa**': p1, 'bb**': p2, 'cc**': p3, 'dd**': p4}
ee = 0 # 判断表情面板开关的标志
# 发送表情图标记的函数, 在按钮点击事件中调用
def mark(exp): # 参数是发的表情图标记, 发送后将按钮销毁
global ee
mes = exp + ':;' + user + ':;' + chat
s.send(mes.encode())
b1.destroy()
b2.destroy()
b3.destroy()
b4.destroy()
ee = 0
# 四个对应的函数
def bb1():
mark('aa**')
def bb2():
mark('bb**')
def bb3():
mark('cc**')
def bb4():
mark('dd**')
def express():
global b1, b2, b3, b4, ee
if ee == 0:
ee = 1
b1 = tkinter.Button(root, command=bb1, image=p1,
relief=tkinter.FLAT, bd=0)
b2 = tkinter.Button(root, command=bb2, image=p2,
relief=tkinter.FLAT, bd=0)
b3 = tkinter.Button(root, command=bb3, image=p3,
relief=tkinter.FLAT, bd=0)
b4 = tkinter.Button(root, command=bb4, image=p4,
relief=tkinter.FLAT, bd=0)
b1.place(x=5, y=248)
b2.place(x=75, y=248)
b3.place(x=145, y=248)
b4.place(x=215, y=248)
else:
ee = 0
b1.destroy()
b2.destroy()
b3.destroy()
b4.destroy()
# 创建表情按钮
eBut = tkinter.Button(root, text='emoji', command=express)
eBut.place(x=5, y=320, width=60, height=30)
# 图片功能代码部分
# 从图片服务端的缓存文件夹中下载图片到客户端缓存文件夹中
def fileGet(name):
PORT3 = 50009
ss2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss2.connect((IP, PORT3))
message = 'get ' + name
ss2.send(message.encode())
fileName = '.\\Client_image_cache\\' + name
print('Start downloading image!')
print('Waiting.......')
with open(fileName, 'wb') as f:
while True:
data = ss2.recv(1024)
if data == 'EOF'.encode():
print('Download completed!')
break
f.write(data)
time.sleep(0.1)
ss2.send('quit'.encode())
# 将图片上传到图片服务端的缓存文件夹中
def filePut(fileName):
PORT3 = 50009
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect((IP, PORT3))
# 截取文件名
print(fileName)
name = fileName.split('/')[-1]
print(name)
message = 'put ' + name
ss.send(message.encode())
time.sleep(0.1)
print('Start uploading image!')
print('Waiting.......')
with open(fileName, 'rb') as f:
while True:
a = f.read(1024)
if not a:
break
ss.send(a)
time.sleep(0.1) # 延时确保文件发送完整
ss.send('EOF'.encode())
print('Upload completed')
ss.send('quit'.encode())
time.sleep(0.1)
# 上传成功后发一个信息给所有客户端
mes = '``#' + name + ':;' + user + ':;' + chat
s.send(mes.encode())
def picture():
# 选择对话框
fileName = tkinter.filedialog.askopenfilename(title='Select upload image')
# 如果有选择文件才继续执行
if fileName:
# 调用发送图片函数
filePut(fileName)
# 创建发送图片按钮
pBut = tkinter.Button(root, text='Image', command=picture)
pBut.place(x=65, y=320, width=60, height=30)
# 截屏函数如下所示
class MyCapture:
def __init__(self, png):
# 变量X和Y用来记录鼠标左键按下的位置
self.X = tkinter.IntVar(value=0)
self.Y = tkinter.IntVar(value=0)
# 屏幕尺寸
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
# 创建顶级组件容器
self.top = tkinter.Toplevel(root, width=screenWidth, height=screenHeight)
# 不显示最大化、最小化按钮
self.top.overrideredirect(True)
self.canvas = tkinter.Canvas(self.top, bg='white', width=screenWidth, height=screenHeight)
# 显示全屏截图,在全屏截图上进行区域截图
self.image = tkinter.PhotoImage(file=png)
self.canvas.create_image(screenWidth / 2, screenHeight / 2, image=self.image)
self.sel = None
# 鼠标左键按下的位置
def onLeftButtonDown(event):
self.X.set(event.x)
self.Y.set(event.y)
# 开始截图
self.sel = True
self.canvas.bind('<Button-1>', onLeftButtonDown)
# 鼠标左键移动,显示选取的区域
def onLeftButtonMove(event):
if not self.sel:
return
global lastDraw
try:
# 删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
self.canvas.delete(lastDraw)
except Exception as e:
print(e)
lastDraw = self.canvas.create_rectangle(self.X.get(), self.Y.get(), event.x, event.y, outline='black')
self.canvas.bind('<B1-Motion>', onLeftButtonMove)
# 获取鼠标左键抬起的位置,保存区域截图
def onLeftButtonUp(event):
self.sel = False
try:
self.canvas.delete(lastDraw)
except Exception as e:
print(e)
sleep(0.1)
# 考虑鼠标左键从右下方按下而从左上方抬起的截图
left, right = sorted([self.X.get(), event.x])
top, bottom = sorted([self.Y.get(), event.y])
pic = ImageGrab.grab((left + 1, top + 1, right, bottom))
# 弹出保存截图对话框
fileName = tkinter.filedialog.asksaveasfilename(title='Save screenshot',
filetypes=[('image', '*.jpg *.png')])
if fileName:
pic.save(fileName)
# 关闭当前窗口
self.top.destroy()
self.canvas.bind('<ButtonRelease-1>', onLeftButtonUp)
# 让canvas充满窗口,并随窗口自动适应大小
self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)
# 开始截图
def buttonCaptureClick():
# 最小化主窗口
root.state('icon')
sleep(0.2)
filename = 'temp.png'
# grab()方法默认对全屏幕进行截图
im = ImageGrab.grab()
im.save(filename)
im.close()
# 显示全屏幕截图
w = MyCapture(filename)
sBut.wait_window(w.top)
# 截图结束,恢复主窗口,并删除临时的全屏幕截图文件
root.state('normal')
os.remove(filename)
# 创建截屏按钮
sBut = tkinter.Button(root, text='Capture', command=buttonCaptureClick)
sBut.place(x=125, y=320, width=60, height=30)
# 文件功能代码部分
# 将在文件功能窗口用到的组件名都列出来, 方便重新打开时会对面板进行更新
list2 = '' # 列表框
label = '' # 显示路径的标签
upload = '' # 上传按钮
close = '' # 关闭按钮
def fileClient():
PORT2 = 50008 # 聊天室的端口为50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IP, PORT2))
# 修改root窗口大小显示文件管理的组件
root['height'] = 390
root['width'] = 760
# 创建列表框
list2 = tkinter.Listbox(root)
list2.place(x=580, y=25, width=175, height=325)
# 将接收到的目录文件列表打印出来(dir), 显示在列表框中, 在pwd函数中调用
def recvList(enter, lu):
s.send(enter.encode())
data = s.recv(4096)
data = json.loads(data.decode())
list2.delete(0, tkinter.END) # 清空列表框
lu = lu.split('\\')
if len(lu) != 1:
list2.insert(tkinter.END, 'Return to the previous dir')
list2.itemconfig(0, fg='green')
for i in range(len(data)):
list2.insert(tkinter.END, ('' + data[i]))
if '.' not in data[i]:
list2.itemconfig(tkinter.END, fg='orange')
else:
list2.itemconfig(tkinter.END, fg='blue')
# 创建标签显示服务端工作目录
def lab():
global label
data = s.recv(1024) # 接收目录
lu = data.decode()
try:
label.destroy()
label = tkinter.Label(root, text=lu)
label.place(x=580, y=0, )
except:
label = tkinter.Label(root, text=lu)
label.place(x=580, y=0, )
recvList('dir', lu)
# 进入指定目录(cd)
def cd(message):
s.send(message.encode())
# 刚连接上服务端时进行一次面板刷新
cd('cd same')
lab()
# 接收下载文件(get)
def get(message):
# print(message)
name = message.split(' ')
# print(name)
name = name[1] # 获取命令的第二个参数(文件名)
# 选择对话框, 选择文件的保存路径
fileName = tkinter.filedialog.asksaveasfilename(title='Save file to', initialfile=name)
# 如果文件名非空才进行下载
if fileName:
s.send(message.encode())
with open(fileName, 'wb') as f:
while True:
data = s.recv(1024)
if data == 'EOF'.encode():
tkinter.messagebox.showinfo(title='Message',
message='Download completed!')
break
f.write(data)
# 创建用于绑定在列表框上的函数
def run(*args):
indexs = list2.curselection()
index = indexs[0]
content = list2.get(index)
# 如果有一个 . 则为文件
if '.' in content:
content = 'get ' + content
get(content)
cd('cd same')
elif content == 'Return to the previous dir':
content = 'cd ..'
cd(content)
else:
content = 'cd ' + content
cd(content)
lab() # 刷新显示页面
# 在列表框上设置绑定事件
list2.bind('<ButtonRelease-1>', run)
# 上传客户端所在文件夹中指定的文件到服务端, 在函数中获取文件名, 不用传参数
def put():
# 选择对话框
fileName = tkinter.filedialog.askopenfilename(title='Select upload file')
# 如果有选择文件才继续执行
if fileName:
name = fileName.split('/')[-1]
message = 'put ' + name
s.send(message.encode())
with open(fileName, 'rb') as f:
while True:
a = f.read(1024)
if not a:
break
s.send(a)
time.sleep(0.1) # 延时确保文件发送完整
s.send('EOF'.encode())
tkinter.messagebox.showinfo(title='Message',
message='Upload completed!')
cd('cd same')
lab() # 上传成功后刷新显示页面
# 创建上传按钮, 并绑定上传文件功能
upload = tkinter.Button(root, text='Upload file', command=put)
upload.place(x=600, y=353, height=30, width=80)
# 关闭文件管理器, 待完善
def closeFile():
root['height'] = 390
root['width'] = 580
# 关闭连接
s.send('quit'.encode())
s.close()
# 创建关闭按钮
close = tkinter.Button(root, text='Close', command=closeFile)
close.place(x=685, y=353, height=30, width=70)
# 创建文件按钮
fBut = tkinter.Button(root, text='File', command=fileClient)
fBut.place(x=185, y=320, width=60, height=30)
# 创建多行文本框, 显示在线用户
listbox1 = tkinter.Listbox(root)
listbox1.place(x=445, y=0, width=130, height=320)
def users():
global listbox1, ii
if ii == 1:
listbox1.place(x=445, y=0, width=130, height=320)
ii = 0
else:
listbox1.place_forget() # 隐藏控件
ii = 1
# 查看在线用户按钮
button1 = tkinter.Button(root, text='Users online', command=users)
button1.place(x=485, y=320, width=90, height=30)
# 创建输入文本框和关联变量
a = tkinter.StringVar()
a.set('')
entry = tkinter.Entry(root, width=120, textvariable=a)
entry.place(x=5, y=350, width=570, height=40)
def call_robot(url, apikey, msg):
data = {
"reqType": 0,
"perception": {
# 用户输入文文信息
"inputText": { # inputText文本信息
"text": msg
},
# 用户输入图片url
"inputImage": { # 图片信息,后跟参数信息为url地址,string类型
"url": "https://cn.bing.com/images/"
},
# 用户输入音频地址信息
"inputMedia": { # 音频信息,后跟参数信息为url地址,string类型
"url": "https://www.1ting.com/"
},
# 客户端属性信息
"selfInfo": { # location 为selfInfo的参数信息,
"location": { # 地理位置信息
"city": "杭州", # 所在城市,不允许为空
"province": "浙江省", # 所在省份,允许为空
"street": "灵隐街道" # 所在街道,允许为空
}
},
},
"userInfo": {
"apiKey": "ee19328107fa41e987a42a064a68d0da", # 你注册的apikey,机器人标识,32位
"userId": "Brandon" # 随便填,用户的唯一标识,长度小于等于32位
}
}
headers = {'content-type': 'application/json'} # 必须是json
r = requests.post(url, headers=headers, data=json.dumps(data))
return r.json()
def send(*args):
# 没有添加的话发送信息时会提示没有聊天对象
users.append('------Group chat-------')
users.append('Robot')
print(chat)
if chat not in users:
tkinter.messagebox.showerror('Send error', message='There is nobody to talk to!')
return
if chat == 'Robot':
print('Robot')
if chat == user:
tkinter.messagebox.showerror('Send error', message='Cannot talk with yourself in private!')
return
mes = entry.get() + ':;' + user + ':;' + chat # 添加聊天对象标记
s.send(mes.encode())
a.set('') # 发送后清空文本框
# 创建发送按钮
button = tkinter.Button(root, text='Send', command=send)
button.place(x=515, y=353, width=60, height=30)
root.bind('<Return>', send) # 绑定回车发送信息
# 视频聊天部分
IsOpen = False # 判断视频/音频的服务器是否已打开
Resolution = 0 # 图像传输的分辨率 0-4依次递减
Version = 4 # 传输协议版本 IPv4/IPv6
ShowMe = True # 视频聊天时是否打开本地摄像头
AudioOpen = True # 是否打开音频聊天
def video_invite():
global IsOpen, Version, AudioOpen
if Version == 4:
host_name = socket.gethostbyname(socket.getfqdn(socket.gethostname()))
else:
host_name = [i['addr'] for i in ifaddresses(interfaces()[-2]).setdefault(AF_INET6, [{'addr': 'No IP addr'}])][
-1]
invite = 'INVITE' + host_name + ':;' + user + ':;' + chat
s.send(invite.encode())
if not IsOpen:
vserver = vachat.Video_Server(10087, Version)
if AudioOpen:
aserver = vachat.Audio_Server(10088, Version)
aserver.start()
vserver.start()
IsOpen = True
def video_accept(host_name):
global IsOpen, Resolution, ShowMe, Version, AudioOpen
vclient = vachat.Video_Client(host_name, 10087, ShowMe, Resolution, Version)
if AudioOpen:
aclient = vachat.Audio_Client(host_name, 10088, Version)
aclient.start()
vclient.start()
IsOpen = False
def video_invite_window(message, inviter_name):
invite_window = tkinter.Toplevel()
invite_window.geometry('300x100')
invite_window.title('Invitation')
label1 = tkinter.Label(invite_window, bg='#f0f0f0', width=20, text=inviter_name)
label1.pack()
label2 = tkinter.Label(invite_window, bg='#f0f0f0', width=20, text='invites you to video chat!')
label2.pack()
def accept_invite():
invite_window.destroy()
video_accept(message[message.index('INVITE') + 6:])
def refuse_invite():
invite_window.destroy()
Refuse = tkinter.Button(invite_window, text="Refuse", command=refuse_invite)
Refuse.place(x=60, y=60, width=60, height=25)
Accept = tkinter.Button(invite_window, text="Accept", command=accept_invite)
Accept.place(x=180, y=60, width=60, height=25)
def video_connect_option():
global Resolution, ShowMe, Version, AudioOpen
video_connect_option = tkinter.Toplevel()
video_connect_option.geometry('150x450')
video_connect_option.title('Connection option')
var1 = tkinter.StringVar()
label1 = tkinter.Label(video_connect_option, bg='#f0f0f0', width=20, text='Resolution ')
label1.pack()
def print_resolution():
global Resolution
Resolution = var1.get()
label1.config(text='Resolution ' + Resolution)
r0 = tkinter.Radiobutton(video_connect_option, text='0', variable=var1, value='0', command=print_resolution)
r0.pack()
r1 = tkinter.Radiobutton(video_connect_option, text='1', variable=var1, value='1', command=print_resolution)
r1.pack()
r2 = tkinter.Radiobutton(video_connect_option, text='2', variable=var1, value='2', command=print_resolution)
r2.pack()
r3 = tkinter.Radiobutton(video_connect_option, text='3', variable=var1, value='3', command=print_resolution)
r3.pack()
r4 = tkinter.Radiobutton(video_connect_option, text='4', variable=var1, value='4', command=print_resolution)
r4.pack()
var2 = tkinter.StringVar()
label2 = tkinter.Label(video_connect_option, bg='#f0f0f0', width=20, text='Protocol version ')
label2.pack()
def print_version():
global Version
Version = var2.get()
label2.config(text='Version IPv' + Version)
v0 = tkinter.Radiobutton(video_connect_option, text='IPv4', variable=var2, value='4', command=print_version)
v0.pack()
v1 = tkinter.Radiobutton(video_connect_option, text='IPv6', variable=var2, value='6', command=print_version)
v1.pack()
var3 = tkinter.StringVar()
label3 = tkinter.Label(video_connect_option, bg='#f0f0f0', width=20, text='Show yourself ')
label3.pack()
def print_show():
global ShowMe
if var3.get() == '1':
ShowMe = True
txt = 'Yes'
else:
ShowMe = False
txt = 'No'
label3.config(text='Show yourself ' + txt)
s0 = tkinter.Radiobutton(video_connect_option, text='Yes', variable=var3, value='1', command=print_show)
s0.pack()
s1 = tkinter.Radiobutton(video_connect_option, text='No', variable=var3, value='0', command=print_show)
s1.pack()
var4 = tkinter.StringVar()
label4 = tkinter.Label(video_connect_option, bg='#f0f0f0', width=20, text='Audio open ')
label4.pack()
def print_audio():
global AudioOpen
if var4.get() == '1':
AudioOpen = True
txt = 'Yes'
else:
AudioOpen = False
txt = 'No'
label4.config(text='Audio open ' + txt)
a0 = tkinter.Radiobutton(video_connect_option, text='Yes', variable=var4, value='1', command=print_audio)
a0.pack()
a1 = tkinter.Radiobutton(video_connect_option, text='No', variable=var4, value='0', command=print_audio)
a1.pack()
def option_enter():
video_connect_option.destroy()
Enter = tkinter.Button(video_connect_option, text="Enter", command=option_enter)
Enter.place(x=10, y=400, width=60, height=35)
Start = tkinter.Button(video_connect_option, text="Start", command=video_invite)
Start.place(x=80, y=400, width=60, height=35)
vbutton = tkinter.Button(root, text="Video", command=video_connect_option)
vbutton.place(x=245, y=320, width=60, height=30)
# 私聊功能
def private(*args):
global chat
# 获取点击的索引然后得到内容(用户名)
indexs = listbox1.curselection()
index = indexs[0]
if index > 0:
chat = listbox1.get(index)
# 修改客户端名称
if chat == '------Group chat-------':
root.title(user)
return
ti = user + ' --> ' + chat
root.title(ti)
# 在显示用户列表框上设置绑定事件
listbox1.bind('<ButtonRelease-1>', private)
# 用于时刻接收服务端发送的信息并打印
def recv():
global users
while True:
data = s.recv(1024)
data = data.decode()
# 没有捕获到异常则表示接收到的是在线用户列表
try:
data = json.loads(data)
users = data
listbox1.delete(0, tkinter.END) # 清空列表框
number = (' Users online: ' + str(len(data)))
listbox1.insert(tkinter.END, number)
listbox1.itemconfig(tkinter.END, fg='green', bg="#f0f0ff")
listbox1.insert(tkinter.END, '------Group chat-------')
listbox1.insert(tkinter.END, 'Robot')
listbox1.itemconfig(tkinter.END, fg='green')
for i in range(len(data)):
listbox1.insert(tkinter.END, (data[i]))
listbox1.itemconfig(tkinter.END, fg='green')
except:
data = data.split(':;')
data1 = data[0].strip() # 消息
data2 = data[1] # 发送信息的用户名
data3 = data[2] # 聊天对象
if 'INVITE' in data1:
if data3 == 'Robot':
tkinter.messagebox.showerror('Connect error', message='Unable to make video chat with robot!')
elif data3 == '------Group chat-------':
tkinter.messagebox.showerror('Connect error', message='Group video chat is not supported!')
elif (data2 == user and data3 == user) or (data2 != user):
video_invite_window(data1, data2)
continue
markk = data1.split(':')[1]
# 判断是不是图片
pic = markk.split('#')
# 判断是不是表情
# 如果字典里有则贴图
if (markk in dic) or pic[0] == '``':
data4 = '\n' + data2 + ':' # 例:名字-> \n名字:
if data3 == '------Group chat-------':
if data2 == user: # 如果是自己则将则字体变为蓝色
listbox.insert(tkinter.END, data4, 'blue')
else:
listbox.insert(tkinter.END, data4, 'green') # END将信息加在最后一行
elif data2 == user or data3 == user: # 显示私聊
listbox.insert(tkinter.END, data4, 'red') # END将信息加在最后一行
if pic[0] == '``':
# 从服务端下载发送的图片
fileGet(pic[1])
else:
# 将表情图贴到聊天框
listbox.image_create(tkinter.END, image=dic[markk])
else:
data1 = '\n' + data1
if data3 == '------Group chat-------':
if data2 == user: # 如果是自己则将则字体变为蓝色
listbox.insert(tkinter.END, data1, 'blue')
else:
listbox.insert(tkinter.END, data1, 'green') # END将信息加在最后一行
if len(data) == 4:
listbox.insert(tkinter.END, '\n' + data[3], 'pink')
elif data3 == 'Robot' and data2 == user:
print('Here:Robot')
apikey = 'ee19328107fa41e987a42a064a68d0da'
url = 'http://openapi.tuling123.com/openapi/api/v2'
print('msg = ', data1)
listbox.insert(tkinter.END, data1, 'blue')
reply = call_robot(url, apikey, data1.split(':')[1])
reply_txt = '\nRobot:' + reply['results'][0]['values']['text']
listbox.insert(tkinter.END, reply_txt, 'pink')
elif data2 == user or data3 == user: # 显示私聊
listbox.insert(tkinter.END, data1, 'red') # END将信息加在最后一行
listbox.see(tkinter.END) # 显示在最后
r = threading.Thread(target=recv)
r.start() # 开始线程接收信息
root.mainloop()
s.close() # 关闭图形界面后关闭TCP连接