我正在关注http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
中给出的示例我有一个线程,它每30秒检查一次sftp服务器的新文件。如果它找到文件,它会将它们上传到数据库,然后它应该触发某些GUI元素的更新,这些元素将从数据库重新加载。
自定义事件代码:
EVT_RESULT_ID = wx.NewId()
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
"""Simple event to carry arbitrary result data."""
def __init__(self, data):
"""Init Result Event."""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
self.data = data
ftp主题:
class FTPThread(threading.Thread):
def __init__(self,wxObject):
"""Init Worker Thread Class."""
threading.Thread.__init__(self)
self.wxObject = wxObject
self._stop = threading.Event()
self._stop.set()
self.start() # start the thread
def run(self):
while True:
time.sleep(30)
if not self._stop.isSet():
wx.CallAfter(self.parseFTP)
def stop(self):
self._stop.set()
def resume(self):
self._stop.clear()
def parseFTP(self):
#connect to db
...
#connect to sftp site
...
files_found=False
#process each file and delete
for file in dirlist:
files_found=True
...#process into db
sftp.remove(file)
sftp.close()
t.close()
#trigger update event if files found
if files_found==True:
wx.PostEvent(self.wxObject, ResultEvent("Files found"))
其中一个GUI元素:
class MyGrid(wx.grid.Grid):
def __init__(self, parent):
wx.grid.Grid.__init__(self, parent,-1,style=wx.EXPAND)
self.parent=parent
...
self.update()
EVT_RESULT(self, self.updateFromEvent)
def updateFromEvent(self,event):
self.update()
def update(self):
...
在调试之后,正在创建wx.PostEvent,但不会触发网格中的任何响应。
我可以在示例和我的代码之间找到的唯一区别是,在示例中,EVT_RESULT位于主框架中,而不是GUI元素 - 这是否需要?
答案 0 :(得分:1)
事件不会传播给它的子节点,因此如果MyGrid是主框架的子节点,则在main中发布的事件将不会传递给MyGrid。你可以做的是将事件处理程序直接绑定到MyGrid实例中的函数,如:
"""from MainWindow"""
self._workerthread = FtpThread(...)
self._mygrid = MyGrid(...)
# Bind event
EVT_RESULT(self, self._mygrid.updateFromEvent)
我不太熟悉这种绑定,因为我通常使用wx.Bind。
答案 1 :(得分:0)
我不确定,但该示例基于维基中的某些内容:http://wiki.wxpython.org/LongRunningTasks
我怀疑,因为它说“赢”作为参数,它可能指的是顶级窗口,所以可能需要wx.Frame。您仍然可以从帧中更新网格。
编辑:曼尼有一个好点。这可能也会奏效。并且pubsub摇滚!