【问题标题】:Using python websocket client with tkinter将 python websocket 客户端与 tkinter 一起使用
【发布时间】:2015-11-14 23:25:19
【问题描述】:

我正在尝试在 python 2.7 中使用 websocket 客户端。客户端在使用 IDLE 运行时工作正常,如收到的消息所示。但是,尝试在 tkinter 文本小部件中插入 websocket 消息不起作用。消息仍在 IDLE 中显示,但 tkinter 窗口根本不显示。

我正在使用的包名为 websocket-client 0.32.0,我从here 下载了它。我按照关于如何制作类似 api 的 javascript 的说明进行了一些修改。

这是我的代码:

from Tkinter import *
from websocket import *

master = Tk()
master.wm_title("Websocket Test")
minwidth = master.winfo_screenwidth()/4*3
minheight = master.winfo_screenheight()/4*3
master.minsize(width=minwidth, height=minheight)
master.resizable(0,0)

text = Text(master)
text.pack(expand=True,fill=BOTH)

def on_message(ws, message):
   text.insert(END, message+"\n")
   print "Received: "+message
   return

def on_error(ws, error):
   text.insert(END, error+"\n")
   print error
   return

def on_close(ws):
   text.insert(END, "### closed ###\n")
   print "### closed ###"
   return

def on_open(ws):
   ws.send("hi")
   ws.send("test")
   return

enableTrace(True)
ws = WebSocketApp("ws://echo.websocket.org/", on_message = on_message, on_error = on_error, on_close = on_close)
ws.on_open = on_open

ws.run_forever()

master.mainloop()

如果这也有帮助,下面是 IDLE 中显示的内容:

--- request header ---
GET / HTTP/1.1

Upgrade: websocket

Connection: Upgrade

Host: echo.websocket.org

Origin: http://echo.websocket.org

Sec-WebSocket-Key: tXWAVVlaRoq2S4+p/z12gg==

Sec-WebSocket-Version: 13




-----------------------
--- response header ---
HTTP/1.1 101 Web Socket Protocol Handshake
Connection: Upgrade
Date: Fri, 21 Aug 2015 05:16:54 GMT
Sec-WebSocket-Accept: LH12LFLFaek6HgCnGIugF0sg9lA=
Server: Kaazing Gateway
Upgrade: websocket
-----------------------
send: '\x81\x82{b\x97\xfc\x13\x0b'
send: '\x81\x84\xa5J\xecf\xd1/\x9f\x12'
Received: hi
Received: test

我已经被这个问题困扰了一段时间,我找不到任何解决此类问题的方法。由于我是新手,任何帮助表示赞赏。

【问题讨论】:

  • 我猜 tkinter 窗口甚至没有出现?
  • 不,窗口不显示。我非常希望将收到的内容添加到文本小部件中。
  • 您可以使用我的this answer 中显示的errorwindow 模块,并将您的websocket 处理函数print() 用于另一个窗口。这将消除在每个人中调用text.insert() 的需要。实际上,您在所涉及的两个无限循环(wbsocket 和 tkinter)之间进行多任务处理。

标签: python python-2.7 tkinter websocket


【解决方案1】:

好吧,我不使用 websocket ,但问题似乎是,当你这样做时 -

ws.run_forever()

应用程序进入无限循环,因此控制永远不会到达master.mainloop(),这是 tkinter 显示所必需的,这又是另一个无限循环,只有在您关闭 gui 时才会退出。

你真正想要的是同时运行两个无限循环,这需要你在两个不同的线程中运行它们,目前它们都定义在同一个线程上,所以一个只会在另一个退出后运行。

一个快速的解决方法是使用 master.after() 有一定的延迟并给出一个函数,然后在函数中为 websocket 连接到服务器的函数启动一个新线程。这样两个无限循环都在不同的线程中。

但最好的解决方法是使用一个按钮,我们称之为'Connect'。然后该按钮的回调将是下面的on_connect() 之类的函数,它启动连接函数-

def connect_to_socket():
    enableTrace(True)
    ws = WebSocketApp("ws://echo.websocket.org/", on_message = on_message, on_error = on_error, on_close = on_close)
    ws.on_open = on_open

    ws.run_forever()

def on_connect():
    import threading
    t = threading.Thread(target=connect_to_socket)
    t.start()

按钮类似于 -

button = Button(master, text="Connect", command=on_connect)

然后你可以随意放置按钮。

【讨论】:

    【解决方案2】:

    感谢 Anand 的回复,我能够找出问题所在。工作和更新的代码发布在下面:

    from Tkinter import *
    from websocket import *
    from threading import *
    
    master = Tk()
    master.wm_title("Team Black Client")
    master.withdraw()
    minwidth = master.winfo_screenwidth()/4*3
    minheight = master.winfo_screenheight()/4*3
    master.minsize(width=minwidth, height=minheight)
    x = (master.winfo_screenwidth() - minwidth)/2
    y = (master.winfo_screenheight() - minheight)/2
    master.geometry("+"+str(x)+"+"+str(y))
    master.deiconify()
    master.resizable(0,0)
    
    text = Text(master)
    text.pack(expand=True,fill=BOTH)
    
    def on_message(ws, message):
       text.insert(END, message+"\n")
       print "Received: "+message
       return
    
    def on_error(ws, error):
       text.insert(END, error+"\n")
       print error
       return
    
    def on_close(ws):
       text.insert(END, "### closed ###\n")
       print "### closed ###"
       return
    
    def on_open(ws):
       ws.send("hi")
       ws.send("test")
       return
    
    def connection():
       enableTrace(True)
       ws = WebSocketApp("ws://echo.websocket.org/", on_message = on_message, on_error = on_error, on_close = on_close)
       ws.on_open = on_open
    
       ws.run_forever()
       return
    
    t = Thread(target=connection)
    t.start()
    
    master.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2011-12-19
      • 2021-01-21
      • 2016-12-29
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 2012-10-16
      • 2013-06-18
      相关资源
      最近更新 更多