我正在尝试在我的Tkinter窗口旁边运行一个无限循环(有一个中断)并与其上的小部件交互。是的,我已经完成了我的研究,但是当我运行我的代码并激活该功能时,窗口停止响应。
我已从方法中删除了“while true”,并在其末尾放置了:
if self.connected:
root.after(100, self.listenServer(id, req))
我认为问题是该函数需要一段时间才能完成(我正在制作一个包含的客户端,因此它必须连接到服务器)。我可以告诉它运行了六次,因为我在方法中放了一个print语句。
是否有一个简单的(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))
是的,我知道这对写入文本小部件的方式效率很低。我尝试制作一种方法来更轻松地完成它,但它无法正常工作。一旦我开始运行,我会担心这一点。
答案 0 :(得分:2)
这里的问题是窗口需要不断更新,以便窗口对输入做出反应 - 这是程序工作方式的现实,也是有道理的。
另一方面,你想在循环中做一些不允许窗口更新的东西 - 鉴于此,窗口无法做出反应。
所以不,没有解决方案,不会以某种方式涉及线程或多处理 - 你需要同时做两件事。
如果您不想直接处理线程,可以使用twisted
这样的库来提供您正在谈论的网络,这样可以避免您等待请求完成。
另一个主要选项是使用multiprocessing
module或threading
module移动您想要同时执行的操作,以将您的界面更新为新的线程/进程。
答案 1 :(得分: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交互。我的程序有时会因此而崩溃。