开发者

wxpython event not triggering

开发者 https://www.devze.com 2023-04-09 20:10 出处:网络
I\'m following the example given in http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

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 ft开发者_开发问答p 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!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号