1

Tkinter ウィンドウと一緒に実行され、そのウィンドウ上のウィジェットと対話する無限ループ (休憩あり) を作成しようとしています。はい、調査を行いましたが、コードを実行して機能を有効にすると、ウィンドウが応答しなくなります。

メソッドから「while true」を削除し、最後に次を配置しました。

if self.connected:
    root.after(100, self.listenServer(id, req))

問題は、関数が完了するまでに少し時間がかかることだと思います (私は Omegle クライアントを作成しているため、サーバーに接続する必要があります)。メソッドにprintステートメントを入れているので、6回実行されていることがわかります。

この問題を解決する簡単な(AKA スレッドなし)方法はありますか?

まあ、スレッド化しか方法がないなら、それでいいと思います。

これが私の接続方法とリッスン方法です。

    def listenServer(self, id, req):
    site = url.urlopen(req)

    #We read the HTTP output to get what's going on
    rec = site.read()

    if 'waiting' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Waiting...\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'connected' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger connected\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'strangerDisconnected' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger Disconnected\n", "italic")
        self.chatbox.config(state=DISABLED)
        self.connected = False

    elif 'typing' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger is typing\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'gotMessage' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger: " + rec[17:len(rec) - 3] + "\n")
        self.chatbox.config(state=DISABLED)

def OmegleConnect(self):
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Connecting...\n", "italic")
    self.chatbox.config(state=DISABLED)

    site = url.urlopen('http://omegle.com/start', '')
    id = site.read()
    id = id[1:len(id) - 1]
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Stranger ID: " + id + "\n", "title")
    self.chatbox.config(state=DISABLED)
    req = url.Request('http://omegle.com/events', urllib.urlencode({'id':id}))
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Finding a stranger...\n", "italic")
    self.chatbox.config(state=DISABLED)
    self.connected = True
    root.after(100, self.listenServer(id, req))

はい、テキストウィジェットへの書き込み方法が非常に非効率的であることはわかっています。もっと簡単にできる方法を作ってみたのですが、うまくいきませんでした。これが出来上がったら気になります。

4

2 に答える 2

2

ここでの問題は、ウィンドウが入力に反応するために、ウィンドウを継続的に更新する必要があるということです。これは、プログラムの動作の現実であり、理にかなっています。

一方、ウィンドウの更新を許可しないループで何かを実行したい場合 - これを考えると、ウィンドウが反応する方法はありません。

いいえ、なんらかの方法でスレッド化やマルチプロセッシングを伴わない解決策はありません。一度に 2 つのことを行う必要があります。

可能な解決策:

スレッド化を直接処理したくない場合は、ライブラリなどtwistedを使用して、話しているネットワークを提供できます。これにより、リクエストが完了するのを待つ必要がなくなります。

もう1つの主なオプションは、multiprocessingモジュールまたはthreadingモジュールを使用して、同時にやりたいことを移動して、インターフェイスを新しいスレッド/プロセスに更新することです。

于 2012-05-05T15:11:52.910 に答える
0

スレッド化を使用したくない場合:

tkinterwidget.update() # repaint & use events

または何かをスケジュールしたい場合:

class MainWindo(Tk):

    ...

    def method(self):
        # do something here for every 100 ms
        if loop:
            self.after(100, self.method)

2 つのスレッドから Tkinter を操作しないように注意してください。これが原因で、マイ プログラムがクラッシュすることがありました。

于 2012-05-05T16:10:01.673 に答える