1

我正在尝试创建一个无限循环(带中断),它在我的 Tkinter 窗口旁边运行并与它上面的小部件进行交互。是的,我已经完成了我的研究,但是当我运行我的代码并激活该功能时,窗口停止响应。

我已经从方法中删除了“while true”,并在它的末尾放置:

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

我认为问题在于该功能需要一些时间才能完成(我正在制作一个 Omegle 客户端,因此它必须连接到服务器)。我可以说它运行了六次,因为我在方法中放了一条打印语句。

有没有一种简单的(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

这里的问题是窗口需要不断更新,以便窗口对输入做出反应——这是程序工作方式的现实,并且是有意义的。

另一方面,您想在不允许窗口更新的循环中执行某些操作 - 鉴于此,窗口无法做出反应。

所以不,没有解决方案不会以某种方式涉及线程或多处理 - 你需要一次做两件事。

可能的解决方案:

如果您不想直接处理线程,您可以使用一个库twisted来提供您正在谈论的网络,这将避免您等待您的请求完成。

另一个主要选项是使用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)

注意不要从两个线程与 Tkinter 交互。我的程序有时会因此而崩溃。

于 2012-05-05T16:10:01.673 回答