0

現時点では、GUI とネットワーク プログラミングに関してはまだ初心者なので、これが非常に簡単な修正になることを願っています。tkinter モジュールと asyncore モジュールについて、それぞれにいくつかのプログラムを構築することについて非常に基本的な理解がありますが、プログラムで両方を一緒に使用するのに問題があります。UI 全体をまとめてみたところ、重要な非同期ネットワーク機能を実現できなかったことがわかりました。簡単にするために、私が抱えている基本的な問題を説明するために、プログラムを最も単純な形式に分解しました。コードは次のとおりです。

from Tkinter import *
import asyncore, socket

class Application(object):
    def __init__(self, root):
        mainFrame = Frame(root)
        mainFrame.grid(column=1, row=1, columnspan=3, rowspan=1)
        mainButton = Button(mainFrame, text='Click', command=self.makeSocket)
        mainButton.grid(column=2, row=1, columnspan=1, rowspan=1, pady=7, padx=40)

    def makeSocket(self):
        clientSocket()

class clientSocket(asyncore.dispatcher):
    def __init__(self):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect(("XXX.XXX.XXX.XXX", XXXX))
        print 'init works'

    def handle_connect(self):
        print 'connect works'

root = Tk()
myApp = Application(root)
root.after_idle(asyncore.loop) 
root.mainloop()

そのため、プログラムを実行してボタンをクリックすると、文字列「init works」が表示され、clientSocket オブジェクトが初期化され、接続が正常に確立されたことを示します。ただし、handle_connect メソッドは実行されません。また、handle_read メソッドを実装してサーバーでコマンドを実行すると (データをクライアントに送り返すため)、このメソッドも呼び出されません。非同期コア ループの単独での実行を妨げている一般的な問題があると考えています。tkinter イベント ループが原因である可能性があることは認識していますが、after_idle メソッドを使用すると、GUI がアイドル状態のときに Tkinter 以外のイベントを処理できるようになるという印象を受けました。まだ問題を引き起こしているのはtkinterイベントループですか、それとも何か他のものでしょうか?

4

2 に答える 2

2

ここにはいくつかの問題があり、どれが問題なのかわかりません。

asyncore.loop は、正常に動作している場合は戻らない関数です。root.mainloop はおそらく、ウィンドウを閉じるまで戻らない関数です。そのため、ある時点で一方のループが他方のループによって一定期間枯渇するため、問題が発生する可能性があります。

(ちなみに、これが、メイン ループを置き換えてイベント駆動型システムに置き換えることで、使いやすくしようとするフレームワークが嫌いな理由です。これらのシステムを 2 つ以上一緒に使用する必要が生じるまでは、うまく機能します。物事が混乱する可能性があります。)

ただし、asyncore.loop が繰り返される回数を制限できます。代わりにこれを試してください:

def poll_asyncore_once():
    asyncore.loop(count=1)

root.after_idle(poll_asyncore_once) 

ループ呼び出しにも、1 秒未満のタイムアウト値を追加したい場合があります。

ただし、非同期コア ループに入った結果、GUI でイベントが不足したとしても、最終的には接続が確立されると考えていました。これは、何か他の問題が発生したことを意味します。asyncore が connect() メソッドで例外を発生させ、TK がそれを飲み込んでいる可能性があります。clientSocket に例外ハンドラを配置してみてください。初期化して、様子を見てください。

于 2010-01-01T12:19:25.777 に答える
0

asyncore と Tkinter を一緒に使用する方法を示している Jacob Hallén によるこのレシピを参照してください (基本的には、スレッドのトリックを使用します)。(Python クックブックの初版ではレシピ 9.6 として、第 2 版では 11.4 として拡張されています)。

于 2010-01-01T17:40:00.270 に答える