在这一点上,当涉及到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方法并在服务器上执行命令(将数据发送回客户端),该方法也不会被调用。我认为有一些一般性的问题阻碍了asyncore循环的独立运行。我意识到tkinters事件循环可能是罪魁祸首,但我的印象是after_idle方法允许在图形用户界面空闲时处理非Tkinter事件。是tkinter事件循环仍在导致问题,还是其他原因?
发布于 2010-01-01 20:19:26
这里有几个问题,我不确定是哪一个问题。
asyncore.loop是一个永远不会返回的函数,当一切正常工作时。root.mainloop可能是一个在关闭窗口之前永远不会返回的函数。因此,事情很可能会出错,因为在某一时刻,一个循环将被另一个循环饥饿一段时间。
(顺便说一句,这就是为什么我不喜欢试图通过替换主循环并将其替换为事件驱动系统来简化其使用的框架-它工作得很好,直到您需要同时使用两个或更多这样的系统,这时事情可能会变得混乱。)
但是,您可以限制asyncore.loop的迭代次数。试着这样做:
def poll_asyncore_once():
asyncore.loop(count=1)
root.after_idle(poll_asyncore_once) 您可能还想在循环调用中添加一个超时值,即小于一秒的值。
然而,我仍然会认为,即使GUI最终由于您进入异步核心循环而导致事件匮乏,连接最终也会完成。这意味着有些地方出了问题,可能是asyncore在connect()方法中引发了异常,而TK正在吞并它。尝试在clientSocket.init中放置一个异常处理程序,看看效果如何。
发布于 2010-01-02 01:40:00
请参阅雅各布·霍伦的this recipe,展示如何一起使用asyncore和Tkinter (基本上是通过线程技巧)。(它还在Python Cookbook的第一个印刷版中扩展为recipe 9.6,在第二版中扩展为11.4 )。
https://stackoverflow.com/questions/1988286
复制相似问题