発生している問題・エラーメッセージ
tkinterを使用してGUIを作成し、Websocket接続ボタンを押すことで、websocket通信を開始させたいのですが、
ボタンを押すと通信は開始されるが、その後、GUIが一切の入力を受け付けなくなってしまいます。
(画面がホワイトアウトし、くるくるが回っている状態)
下記のコードに問題がある点、対処方法を教えて頂きたいです。
よろしくお願いいたします。
class A: def __init__(self,master): ~~省略 async def connect_ws(self): uri = 'ws://localhost:18080/xxxxxxx/websocket' async with websockets.connect(uri, ping_timeout=None) as ws: while not ws.closed: response = await ws.recv() class Win2(tk.Frame): def __init__(self,master): self.A = A() ~~省略 def create_widgets(self): self.makeorder_button_connectws = ttk.Button(self.labelFrame, text='Websocket接続',command = self.connect_ws) self.makeorder_button_connectws.pack() ~~省略 def connect_ws(self): loop = asyncio.get_event_loop() loop.create_task(self.A.connect_ws()) try: loop.run_forever() except KeyboardInterrupt: exit()
使用しているバージョン
python 3.10
tkinter 8.6
asyncio-3.4.3
tkinter についてはよく知りませんが、async / await を関数の中で使うのであれば、その関数そのものも async で定義する必要があります。
async def connect_ws(self): としてみてください。
ありがとうございます。
tkinterのボタンを押すことで、class Win2 のconnect_wsを呼び出し、
async で定義したclass A のconnect_wsを呼び出し。webscoketの接続を試みましたが、
やはり、GUI(Win2)フリーズしてしまいます。
フリーズしてしまうのは、win2のconnect_wsメソッドが動き続けているからでしょうか.
少し tkinter について調べてみましたが、async の使われ方が、python や tkinter のバージョン、使用しているモジュール等によってかなり違いがあるようです。差し支えなければ、import している tkinter 及び 非同期に関連するモジュールと python 等のバージョンも補足として質問本文に追記すると回答が得られやすくなるかもしれません。
使用しているモジュールのバージョンを追記させていただきました.
よろしくお願いいたします。
def connect_ws(self):
try:
asyncio.run(self.A.connect_ws())
ecept KeyboardInterrupt:
exit()
だと、どうですか? websockets のドキュメントを参考にしました。
https://websockets.readthedocs.io/en/stable/index.html
試してみましたが、やはりwebsocket通信自体は開始されるものの、GUIが操作不能になってしまいます。
tkinterのmainloopの中ではasyncioのloopを動かせないのでしょうか。tkinterとは別のスレッドで動かす等はできるのでしょうか?
役に立ちそうな過去の質問を探してみました。参考にしてみてください。どうやら、tkinter の mainloop の中では asyncio を動かすのは無理っぽいので、thread とかを使うみたいです。
Python3 Tkinter Tkinterとソケット通信のサーバの立ち上げ
https://teratail.com/questions/317832
Python3 非同期処理について
https://teratail.com/questions/331789
asyncioでtkinterのダイアログを開けない
https://teratail.com/questions/199068
Tkinter内でのループ処理
https://teratail.com/questions/299389
Demerara様、ありがとうございました。
threadを用いて、別のスレッドにてasyncioのループを作成することにより、GUIが停止することなくwebsocket接続を行うことができました。
役に立てたようでよかったです。そのコメントの内容を回答欄に書いて自己解決として、この質問を閉じておいてください。

回答2件
あなたの回答
tips
プレビュー