質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

python asyncioを使用した際GUIが動かなくなる

TheBullchannel
TheBullchannel

総合スコア31

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1回答

0グッド

1クリップ

114閲覧

投稿2023/01/24 07:29

編集2023/01/25 11:38

発生している問題・エラーメッセージ

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

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

Demerara

2023/01/24 15:40

tkinter についてはよく知りませんが、async / await を関数の中で使うのであれば、その関数そのものも async で定義する必要があります。 async def connect_ws(self): としてみてください。
TheBullchannel

2023/01/25 07:03

ありがとうございます。 tkinterのボタンを押すことで、class Win2 のconnect_wsを呼び出し、 async で定義したclass A のconnect_wsを呼び出し。webscoketの接続を試みましたが、 やはり、GUI(Win2)フリーズしてしまいます。 フリーズしてしまうのは、win2のconnect_wsメソッドが動き続けているからでしょうか.
Demerara

2023/01/25 08:25 編集

少し tkinter について調べてみましたが、async の使われ方が、python や tkinter のバージョン、使用しているモジュール等によってかなり違いがあるようです。差し支えなければ、import している tkinter 及び 非同期に関連するモジュールと python 等のバージョンも補足として質問本文に追記すると回答が得られやすくなるかもしれません。
TheBullchannel

2023/01/25 11:52

使用しているモジュールのバージョンを追記させていただきました. よろしくお願いいたします。
TheBullchannel

2023/01/25 15:37

試してみましたが、やはりwebsocket通信自体は開始されるものの、GUIが操作不能になってしまいます。 tkinterのmainloopの中ではasyncioのloopを動かせないのでしょうか。tkinterとは別のスレッドで動かす等はできるのでしょうか?
Demerara

2023/01/26 08:44

役に立ちそうな過去の質問を探してみました。参考にしてみてください。どうやら、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
TheBullchannel

2023/01/29 14:33

Demerara様、ありがとうございました。 threadを用いて、別のスレッドにてasyncioのループを作成することにより、GUIが停止することなくwebsocket接続を行うことができました。
Demerara

2023/01/30 11:40

役に立てたようでよかったです。そのコメントの内容を回答欄に書いて自己解決として、この質問を閉じておいてください。

回答1

0

自己解決

class A:
def init(self,master):
~~省略
async def connect_ws(self):
async with websockets.connect('ws://localhost:18080/XXXXXXXXX/websocket', ping_timeout=None) as ws:
while not ws.closed:
response = await ws.recv()
board = json.loads(response)

def createloop(self,loop):
loop.create_task(self.connect_ws())
loop.run_forever()

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.new_event_loop()
thread1 = threading.Thread(target=A.createloop, args=(loop))
thread1.start()

上記のように、あらかじめWin2クラス(メインのクラス)にてasyncioのループを作成しておきます。
次に、asyncioを動かしたいクラス内でloopにタスクを設定し、threading.threadに、loopとともに渡すことにより、
GUIのloopを妨げることなく、別スレッドにてasyncioを動作させることが可能です。

投稿2023/02/01 06:58

TheBullchannel

総合スコア31

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。