wxpython 事件未触发

发布于 2024-12-07 09:18:44 字数 2062 浏览 1 评论 0原文

我正在遵循 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 元素 - 这是必需的吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寒尘 2024-12-14 09:18:44

事件不会传播到其子级,因此如果 MyGrid 是主框架的子级,则在主框架中发布的事件将不会传递到 MyGrid。您可以做的是将事件处理程序直接绑定到 MyGrid 实例中的函数,如下所示:

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

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

我不太熟悉这种绑定,因为我通常使用 wx.Bind。

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.

娇纵 2024-12-14 09:18:44

我不确定,但该示例基于 wiki 中的内容: http://wiki.wxpython.org/ LongRunningTasks

我怀疑,由于它说“win”作为参数,它可能指的是顶级窗口,因此可能需要 wx.Frame。不过,您仍然可以从框架中更新网格。

编辑:曼尼有一个很好的观点。这可能也会起作用。和 pubsub 摇滚!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文