OK,既然可以随时更新,那我就用它来记录我的学习历程啦!
2017/7/3
这个是一次学习的经历...
tkinter 中的frame容器写的那个界面我是直接在网上搜了一个范本...但是frame不会自动显示最末尾一行的内容...输入了之后超出部分无法自动显示...额解决了此问题的小伙伴可以留言讨论哇
客户端demo
这个自娱自乐当中涉及到了代码编码格式转换问题
decode('utf-8')是将utf-8格式的代码自动转换成unicode。print()函数会自动识将Unicode转换成内在需要的编码格式
encode('utf-8')是将其他格式的代码转换成utf-8码,以便将字符串传递给某些内置函数
如上述demo中就需要
s.sendall(text_msg.get('0.0', tk.END).encode('utf-8'))
这样字符串经过处理之后,socket模块中的sendall()函数才能处理获得的数据,否则报错
额...这里面还有一个密码登录界面...
输入密码正确后,会关闭此页面并跳入另一个新界面。这其中mainloop()函数。
通过实验发现...一个程序只允许一个mainlooop()函数的存在。然而,第二个界面是通过第一个界面生成的,所以mainloop()函数先于第二个界面生成。我们知道mainloop作为一个循环是空占cpu的...也就是说在主任务线上的后续操作都被卡死了...所以这里我引入了一个线程,将mainloop丢到一个线程中去,这样大家就能愉快的玩耍啦!
额...涉及线程,我把最简单的事例线程也贴上来啦,大家直接用就好了
2017/7/3
这个是一次学习的经历...
tkinter 中的frame容器写的那个界面我是直接在网上搜了一个范本...但是frame不会自动显示最末尾一行的内容...输入了之后超出部分无法自动显示...额解决了此问题的小伙伴可以留言讨论哇
服务器端demo
# -*- coding: utf-8 -*-
import socket
HOST = ''
PORT = 10022
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'connect successful'
while 1:
data = conn.recv(1024).decode('utf-8')
if data=="":
conn.close()
print 'connect successful'
else:
print data
客户端demo
# -*- coding: utf-8 -*-
import Tkinter as tk
import threading
import datetime
import time
import socket
def sendmessage(*func):
#在聊天内容上方加一行 显示发送人及发送时间
msgcontent = '我:' + time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + '\n '
text_msglist,text_msg = func
text_msglist.insert(tk.END, msgcontent, 'green')
text_msglist.insert(tk.END, text_msg.get('0.0', tk.END))
s.sendall(text_msg.get('0.0', tk.END).encode('utf-8'))
text_msg.delete('0.0', tk.END)
def buttonClick():
password='chenhao'
if entry.get()==password:
show_label.config(text='correct')
password_window.destroy()
root = tk.Tk()
root.title(u'与xxx聊天中')
#创建几个frame作为容器
frame_left_top = tk.Frame(width=380, height=270, bg='white')
frame_left_center = tk.Frame(width=380, height=100, bg='white')
frame_left_bottom = tk.Frame(width=380, height=25)
frame_right = tk.Frame(width=170, height=400, bg='white')
##创建需要的几个元素
text_msglist = tk.Text(frame_left_top)
text_msg = tk.Text(frame_left_center)
button_sendmsg = tk.Button(frame_left_bottom, text='发送',command=lambda:sendmessage(text_msglist,text_msg))
#创建一个绿色的tag
text_msglist.tag_config('green', foreground='#008B00')
#使用grid设置各个容器位置
frame_left_top.grid(row=0, column=0, padx=2, pady=5)
frame_left_center.grid(row=1, column=0, padx=2, pady=5)
frame_left_bottom.grid(row=2, column=0)
frame_right.grid(row=0, column=1, rowspan=3, padx=4, pady=5)
frame_left_top.grid_propagate(0)
frame_left_center.grid_propagate(0)
frame_left_bottom.grid_propagate(0)
#把元素填充进frame
text_msglist.grid()
text_msg.grid()
button_sendmsg.grid(sticky='e')
else:
show_label.config(text='error')
def buttonClick2():
print "ok"
def main():
password_window.mainloop()
t0 = threading.Thread(target=main)
if __name__ == '__main__':
HOST = 'localhost'
PORT = 10022
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print 'connect successful'
password_window = tk.Tk()
button=tk.Button(password_window,text="确认",command = buttonClick)
entry=tk.Entry(password_window,show='*')
label=tk.Label(password_window,text='Password:')
show_label=tk.Label(password_window)
#slider=tk.Scale(password_window,from_=0,to=100)
label.pack()
entry.pack()
button.pack()
show_label.pack()
t0.setDaemon(True)
t0.start()
啊...说一下目前的进度,以及已解决的问题恩...演示版本只能实现由客户端单向发送给服务器端以自娱自乐...
这个自娱自乐当中涉及到了代码编码格式转换问题
decode('utf-8')是将utf-8格式的代码自动转换成unicode。print()函数会自动识将Unicode转换成内在需要的编码格式
encode('utf-8')是将其他格式的代码转换成utf-8码,以便将字符串传递给某些内置函数
如上述demo中就需要
s.sendall(text_msg.get('0.0', tk.END).encode('utf-8'))
这样字符串经过处理之后,socket模块中的sendall()函数才能处理获得的数据,否则报错
额...这里面还有一个密码登录界面...
输入密码正确后,会关闭此页面并跳入另一个新界面。这其中mainloop()函数。
通过实验发现...一个程序只允许一个mainlooop()函数的存在。然而,第二个界面是通过第一个界面生成的,所以mainloop()函数先于第二个界面生成。我们知道mainloop作为一个循环是空占cpu的...也就是说在主任务线上的后续操作都被卡死了...所以这里我引入了一个线程,将mainloop丢到一个线程中去,这样大家就能愉快的玩耍啦!
额...涉及线程,我把最简单的事例线程也贴上来啦,大家直接用就好了
#coding=utf-8
import threading
from time import ctime,sleep
def music(func):
for i in range(2):
print "I was listening to %s. %s" %(func,ctime())
sleep(1)
def move(func):
for i in range(2):
print "I was at the %s! %s" %(func,ctime())
sleep(5)
threads = []
t0 = threading.Thread(target=music,args=("ok",))
threads.append(t0)
t1 = threading.Thread(target=move,args=("haha",))
threads.append(t1)
if __name__ == '__main__':
for t in threads:
t.setDaemon(True)
t.start()
PS:仔细读过客户端代码的盆友可能发现,我的mainloop()是挂在password_window下的,而我紧接着明明将password_window给destory了,为什么我的后续窗口可以正常运行呢?...额,我猜是系统保留了资源供后续使用吧...谁知道呢...我嫌多开一个空的主窗口太冗余了,还要去查怎样隐藏窗口...就酱了啊...(;′⌒`)关于为啥destory了的窗口mainloop()还能正常使用...欢迎大神解惑...
额好像离全双工还远着呢,我目前的想法是做一个 客户端——服务器端——客户端 这样子的由服务器点对点转发消息的聊天机制。想法就是这样辣,我去慢慢拼积木咯
想直接跑代码的同学请先开服务器端,然后再开客户端。不然报错了,我不接受质疑╭(╯^╰)╮
更新于2017 7 12 22:46