简体   繁体   中英

wxpython event not triggering

I'm following the example given in http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

I have a thread which is checking an sftp server for new files every 30 seconds. If it finds files, it uploads them to a db, and then it should trigger an update of certain GUI elements which will reload from the db.

The custom event code:

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

The ftp thread:

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"))

One of the GUI elements:

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):
    ...

Following debugging, the wx.PostEvent is being created, but not triggering any response in the grid.

The only difference I can find between the example and my code is that in the example the EVT_RESULT is in the main Frame, and not a GUI element - is this required?

Events don't propagate to its children so if MyGrid is a child of your main frame, events posted in the main won't make it through to MyGrid. What you can do instead is bind the event handler directly to your function within the instance of MyGrid like so:

"""from MainWindow"""
self._workerthread = FtpThread(...)
self._mygrid = MyGrid(...)

# Bind event
EVT_RESULT(self, self._mygrid.updateFromEvent)

I'm not too familiar with this kind of binding as I typically use wx.Bind.

I'm not sure, but that example was based on something in the wiki: http://wiki.wxpython.org/LongRunningTasks

I suspect that since it says "win" as an argument, it is probably referring to a Top Level Window, so the wx.Frame is probably required. You can still update the grid from the frame though.

EDIT: Manny has a good point. That would probably work too. And pubsub rocks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM