【问题标题】:Multiple wx.Yield() alternative多个 wx.Yield() 替代方案
【发布时间】:2014-03-11 13:43:53
【问题描述】:

我目前有一个 wxpython gui 应用程序,它读取一个不断增长的文本文件并将其打印到 wx.TextCtrl 窗口。我需要同时运行其中的两个,但显然遇到了称为递归错误的 wxYield。 是否有一个简单的替代 wx.Yield 的方法可以让我运行多个?

self.running_log = wx.TextCtrl(self, -1, pos=(5, 5), size=(875,605),
                                       style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

while True:
    wx.Yield()
    fileSize = os.path.getsize(logPath)
    if fileSize > lastSize:
        lines = infile.readlines()
        newLines = 0
        for line in lines[lastLineIndex:]:
            newLines += 1
            print line.rstrip()
        self.running_log.AppendText(line)

【问题讨论】:

  • 在不了解有关代码功能以及所有位如何交互的更多详细信息的情况下,我只能建议threading 可能是要走的路。设置一个线程从文件中读取并在它执行时生成一个事件。然后让该事件触发另一个更新TextCtrl的线程。
  • 我不知道你的代码在做什么,但递归意味着你的wx.Yield() 允许运行某些函数,这也是长时间运行的,因此调用wx.Yield()。您应该确保当您调用 yield 时,它所能做的只是 GUI 更新,并且用户不会导致其他长时间运行的事情发生。
  • 稍微修改了这个问题,以便您可以看到它处于一个永无止境的 while True 循环中。这是我需要穿线的一小部分,或类似的东西。

标签: python wxpython


【解决方案1】:

查看 wxPython wiki:LongRunningTasks。 在那里,您将看到使用 wxYield 的两种替代方法:线程化或将您的处理放入 EVT_IDLE 处理程序。

但是由于您已经在使用 wxYield,所以让我建议您在更改为其他内容之前可以尝试的解决方案:使用标志来指示您是否已经在运行。如果标志为真,不要让代码再次执行 wxYield。

当您调用wx.Yield() 时,wxPython 将控制并处理它需要处理的任何事件。完成后,您的长时间运行的任务将在您的 yield 调用之后再次继续。因此,您可以将所有处理放在一个循环中,并让它在需要时在那里旋转。通过添加一个标志,您可以将入口点限制在收益所在的位置。处理完成后,您可以通过切换标志来释放“锁定”,并且代码的入口点再次变为实际的方法调用。

类似的东西:

if not running:
    running = True
    while True:
        wx.Yield()
        fileSize = os.path.getsize(self.logPath)
        if fileSize > lastSize:
            lines = infile.readlines()
            newLines = 0
            for line in lines[lastLineIndex:]:
                newLines += 1
                self.running_log.AppendText(line)
        # When you are finished, set running to False and break

请注意,检查getsize 的调用频率可能是个好主意。如果它发生得太频繁,您可以通过确保经过一段时间来限制它,以避免过多的调用减慢您的系统。

【讨论】:

  • 谢谢 Michael,这就是它目前的工作方式,但我想添加另一个相同的任务,所以必须查看线程。
  • 如果您将此行为封装到一个类中,您只需创建该类的两个实例,就可以运行您的两个任务。每个实例都有自己的数据,例如self.running,以区分它们。
  • 但是线程很好,只要确保您没有从任何线程更新 GUI,而是将事件发送到 GUI 线程。
【解决方案2】:

wx.SafeYield() 不是为解决这个问题而设计的吗?

例如,请参阅此处enter link description here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多