【问题标题】:What is the simplest way of monitoring when a wxPython frame has been resized?当 wxPython 框架调整大小时,最简单的监控方法是什么?
【发布时间】:2012-11-08 21:52:26
【问题描述】:

我想知道何时调整了框架的大小,以便保存大小并在下次应用程序启动时记住它。这是我的on_resize 方法:

def on_resize(self, event):
    logic.config_set('main_frame_size',
                     (event.Size.width, event.Size.height))

    event.Skip()

它是这样绑定的:

self.Bind(wx.EVT_SIZE, self.on_resize)

问题在于性能。为安全起见,我的逻辑模块在每次设置更改时都会保存配置文件,而每次触发调整大小事件时都编写配置文件对性能造成太大影响。

当用户完成调整框架大小时,最好/最简单的监控方式是什么?


更新

我的config_set 功能:

def config_set(key, value):
    """Set a value to the config file."""
    vprint(2, 'Setting config value: "{}": "{}"'.format(key, value))

    config[key] = value

    # Save the config file.
    with open(config_file_path, 'w') as f:
        pickle.dump(config, f)

【问题讨论】:

    标签: python wxpython wxwidgets


    【解决方案1】:

    您可以处理当事件队列为空时触发的EVT_IDLE

    wx.IdleEvent:此类用于EVT_IDLE 事件,这些事件在应用程序空闲时生成并发送。换句话说,当事件队列变空时,空闲事件被发送到所有窗口(默认情况下),只要它们都没有调用 RequestMore,那么直到系统事件队列有一些正常事件之后,才会有空闲事件,并且然后又变空了。

    调整大小或移动窗口的过程应保持事件队列阻塞,以便在调整大小/移动完成之前它不会变空(并触发空闲事件)。

    EVT_SIZE 中设置一个脏标志并在EVT_IDLE 处理程序中检查它。如果设置了标志,则保存新大小并重置标志:

    import wx
    
    class Frame(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self,None)
            self.resized = False # the dirty flag
            self.Bind(wx.EVT_SIZE,self.OnSize)
            self.Bind(wx.EVT_IDLE,self.OnIdle)
    
        def OnSize(self,event):
            self.resized = True # set dirty
    
        def OnIdle(self,event):
            if self.resized: 
                # take action if the dirty flag is set
                print "New size:", self.GetSize()
                self.resized = False # reset the flag
    
    app = wx.PySimpleApp()
    frame = Frame().Show()
    app.MainLoop()
    

    EVT_SIZE 也可能在还原最小化窗口时触发(窗口大小保持不变)。如果您想减少不必要的保存,您可能需要在将其保存到配置之前检查大小是否实际不同(您可以在包含上次保存大小的变量中跟踪它)。

    您可能需要添加EVT_MOVE 以跟踪窗口位置。

    【讨论】:

      【解决方案2】:

      您绝对不应该在每次调整大小时保存窗口几何图形,通常应该只在框架关闭时完成。如果您想要额外的安全性(但是,老实说,您如何设法在 Python 中崩溃?),您还可以从 EVT_TIMER 处理程序调用在帧关闭时调用的相同函数。但是窗口几何图形几乎不是关键资源,所以我认为没有任何真正需要这样做。

      【讨论】:

        【解决方案3】:

        您可以启动一个计时器并让它每隔一段时间检查一次更改,有点像 Microsoft Word 中的自动保存。或者,您可以在 EVT_SIZING 或 EVT_SIZE 发生时设置某种标志,然后绑定到 EVT_LEAVE_WINDOW,因为当您完成调整大小时,您几乎肯定会离开窗口。因此,当该事件触发时,您检查已设置的标志,如果已设置,则保存并重置标志。

        【讨论】:

          【解决方案4】:

          在windows上,您可以将配置保存在注册表中,这样在调整窗口大小时不会影响性能。

          在没有注册表的其他操作系统上,我猜您需要使用文件。但是,令我惊讶的是,即使这样也会造成您会注意到的那种性能损失。

          您是否确定您看到的任何糟糕的表现都是由于这个原因? (也许你的重绘代码很慢?)

          我认为任何现代操作系统都会在不妨碍您的情况下处理如此小的文件写入。可能是 Python 的问题?

          我敦促您先研究上述问题。但是,要回答您的实际问题:

          这样做的方法是将窗口大小保存在一个变量中,并且仅在您的应用程序退出时将其写入文件。


          查看了您刚刚发布的代码。我不是 python 专家,但看起来你每次更新都重新打开文件。如果是这样,难怪它很慢!

          1. 始终保持文件打开。

          2. 仅在您的应用退出时写入文件。

          你也可以看看 wxWidget wxConfig 类。

          【讨论】:

          • 我可以肯定地说,与我移除绑定时相比,窗口现在卡顿和冻结。我并不觉得这很奇怪,因为我使用的是一台旧笔记本电脑,它的磁盘转速为 5200 RPM,可能损坏也可能没有损坏。我仍然觉得每秒编写 20-30 次配置文件很浪费,所以我正在寻找 setTimeout/clearTimeout(来自 JavaScript)方法。
          猜你喜欢
          • 2018-03-03
          • 1970-01-01
          • 2011-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-04
          • 2011-04-21
          相关资源
          最近更新 更多