如何确定哪个子项 windows 在 ScrolledWindow during/after 和 EVT_SCROLLED_WIN 事件中可见?
How can I determine which child windows will be visible in a ScrolledWindow during/after a EVT_SCROLLED_WIN event?
我正在为我的应用程序构建一个包含大量缩略图的面板;它们不会全部放入 window,所以我使用 ScrolledWindow 来保存它们并允许用户滚动查看它们。
生成缩略图需要一些时间,因此我尝试优先为 window 中当前可见的缩略图生成图像。我还想捕获哪些缩略图是可见的,这样如果我添加或删除缩略图的一个子集,我就知道滚动条的位置以包含尽可能多的以前可见的缩略图。
我遇到的问题是 EVT_SCROLLWIN 似乎是在子 windows 重新定位到 ScrolledWindow 的客户区之前发布的;换句话说,我正在测量滚动条移动之前的可见对象。有没有办法:a)强制 ScrolledWindow 更新子 window 位置,b)可靠地确定新客户端 window 偏移量与现在相比的偏移量,或者 c)调用发生此更新后的事件处理程序?
如果重要的话,我在这台电脑上是 运行 Python 2.7.11 和 wxPython 3.0.2.0。
代码段如下:
class ThumbsViewer(wx.ScrolledWindow):
def __init__(self, parent, info, style = wx.BORDER_RAISED | wx.HSCROLL):
wx.ScrolledWindow.__init__(self, parent = parent, id = wx.ID_ANY, size = wx.DefaultSize,
pos = wx.DefaultPosition, style = style, name = "ThumbsViewer")
self.__info__ = info
self.__bitmapctrls__ = []
self.__selected__ = []
self.__lastclicked__ = []
self.Bind(wx.EVT_SCROLLWIN, self.__OnScroll__)
# ... Code to generate placeholder thumbnails, arrange buttons, size window, etc. ...
# ... Various functions to handle clicking on thumbnails, etc. ...
# EVT_SCROLLWIN Handler - Measure client window positions and determine which are
# visible on the screen.
def __OnScroll__(self, event):
if event:
event.Skip()
priority = []
clientsize = self.GetClientSize()
for ctrl in self.__bitmapctrls__:
pos = ctrl.GetPosition()
size = ctrl.GetSize()
# Test to see if any part of the thumbnail control falls within the client
# area...append to the priority list if it does.
# This appears to be where the problem is - the child window positions
# have not been updated to reflect the new scrollbar position yet.
if (((pos[0] >= 0 and pos[0] <= clientsize[0]) or (pos[0] + size[0] >= 0 and pos[0] + size[0] <= clientsize[0]))
and ((pos[1] >= 0 and pos[1] <= clientsize[1]) or (pos[1] + size[1] >= 0 and pos[1] + size[1] <= clientsize[1]))):
priority.append(ctrl.GetPage())
self.__info__.SetPriorityPages(priority)
在为此苦苦挣扎了一段时间之后,我决定绑定 EVT_PAINT 而不是 EVT_SCROLLWIN,并在发生这种情况时检查滚动条。重绘发生在 EVT_SCROLLWIN 和子 window 位置更新之后。
我对这个解决方案不是很满意,因为 EVT_PAINT 发生的原因有很多,与滚动条无关,所以如果你有更好的解决方案,请随时指出.幸运的是,在这种情况下,计算会很快失败,除非我添加或删除缩略图(大多数绘画事件不会发生这种情况),因此性能影响很小。
我正在为我的应用程序构建一个包含大量缩略图的面板;它们不会全部放入 window,所以我使用 ScrolledWindow 来保存它们并允许用户滚动查看它们。
生成缩略图需要一些时间,因此我尝试优先为 window 中当前可见的缩略图生成图像。我还想捕获哪些缩略图是可见的,这样如果我添加或删除缩略图的一个子集,我就知道滚动条的位置以包含尽可能多的以前可见的缩略图。
我遇到的问题是 EVT_SCROLLWIN 似乎是在子 windows 重新定位到 ScrolledWindow 的客户区之前发布的;换句话说,我正在测量滚动条移动之前的可见对象。有没有办法:a)强制 ScrolledWindow 更新子 window 位置,b)可靠地确定新客户端 window 偏移量与现在相比的偏移量,或者 c)调用发生此更新后的事件处理程序?
如果重要的话,我在这台电脑上是 运行 Python 2.7.11 和 wxPython 3.0.2.0。
代码段如下:
class ThumbsViewer(wx.ScrolledWindow):
def __init__(self, parent, info, style = wx.BORDER_RAISED | wx.HSCROLL):
wx.ScrolledWindow.__init__(self, parent = parent, id = wx.ID_ANY, size = wx.DefaultSize,
pos = wx.DefaultPosition, style = style, name = "ThumbsViewer")
self.__info__ = info
self.__bitmapctrls__ = []
self.__selected__ = []
self.__lastclicked__ = []
self.Bind(wx.EVT_SCROLLWIN, self.__OnScroll__)
# ... Code to generate placeholder thumbnails, arrange buttons, size window, etc. ...
# ... Various functions to handle clicking on thumbnails, etc. ...
# EVT_SCROLLWIN Handler - Measure client window positions and determine which are
# visible on the screen.
def __OnScroll__(self, event):
if event:
event.Skip()
priority = []
clientsize = self.GetClientSize()
for ctrl in self.__bitmapctrls__:
pos = ctrl.GetPosition()
size = ctrl.GetSize()
# Test to see if any part of the thumbnail control falls within the client
# area...append to the priority list if it does.
# This appears to be where the problem is - the child window positions
# have not been updated to reflect the new scrollbar position yet.
if (((pos[0] >= 0 and pos[0] <= clientsize[0]) or (pos[0] + size[0] >= 0 and pos[0] + size[0] <= clientsize[0]))
and ((pos[1] >= 0 and pos[1] <= clientsize[1]) or (pos[1] + size[1] >= 0 and pos[1] + size[1] <= clientsize[1]))):
priority.append(ctrl.GetPage())
self.__info__.SetPriorityPages(priority)
在为此苦苦挣扎了一段时间之后,我决定绑定 EVT_PAINT 而不是 EVT_SCROLLWIN,并在发生这种情况时检查滚动条。重绘发生在 EVT_SCROLLWIN 和子 window 位置更新之后。
我对这个解决方案不是很满意,因为 EVT_PAINT 发生的原因有很多,与滚动条无关,所以如果你有更好的解决方案,请随时指出.幸运的是,在这种情况下,计算会很快失败,除非我添加或删除缩略图(大多数绘画事件不会发生这种情况),因此性能影响很小。