簡體   English   中英

使用 python websocket 客戶端與 tkinter

[英]Using python websocket client with tkinter

我正在嘗試在 python 2.7 中使用 websocket 客戶端。 客戶端在使用 IDLE 運行時工作正常,如接收到的消息所示。 但是,嘗試在 tkinter 文本小部件中插入 websocket 消息無效。 IDLE 中還在顯示消息,但是 tkinter window 根本沒有顯示。

我正在使用的 package 稱為 websocket-client 0.32.0,我從這里下載了它。 我按照有關如何制作 javascript(如 api)的說明進行操作,並對代碼進行了一些調整。

這是我的代碼:

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

我已經堅持了一段時間,但找不到解決此類問題的任何方法。 任何幫助表示贊賞,因為我是新手。

好吧,我不使用 websocket,但問題似乎是,當你使用 -

ws.run_forever()

應用程序進入無限循環,因此控件永遠不會到達master.mainloop() ,這是 tkinter 顯示所必需的,這又是另一個無限循環,只有在關閉 gui 時才會退出。

你真正想要的是同時運行兩個無限循環,這需要你在兩個不同的線程中運行它們,目前它們都定義在同一個線程上,所以一個只會在另一個退出后運行。

一個快速的解決方法是使用master.after()並有一定的延遲並給出 function,然后在 function 中為 function 啟動一個新線程,其中 websocket 連接到服務器。 這樣兩個無限循環都在不同的線程中。

但最好的解決辦法是使用一個按鈕,我們稱之為'Connect' 那么該按鈕的回調將是一個 function,就像下面的on_connect()一樣,它啟動 function 進行連接 -

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)

然后您可以根據需要放置按鈕。

多虧了阿南德的回應,我才能夠找出問題所在。 工作和更新的代碼發布在下面:

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM