【问题标题】:How can I determine which child windows will be visible in a ScrolledWindow during/after a EVT_SCROLLED_WIN event?如何确定在 EVT_SCROLLED_WIN 事件期间/之后哪些子窗口将在 ScrolledWindow 中可见?
【发布时间】:2016-02-11 16:27:40
【问题描述】:

我正在为我的应用程序构建一个面板,其中包含大量缩略图;它们不会全部放入窗口中,所以我使用 ScrolledWindow 来保存它们并允许用户滚动查看它们。

生成缩略图图像需要一些时间,因此我尝试优先处理当前在窗口中可见的缩略图图像的生成。我还想捕获哪些缩略图是可见的,这样如果我添加或删除缩略图的子集,我就知道将滚动条放置在哪里,以尽可能多地包含以前可见的缩略图。

我遇到的问题是 EVT_SCROLLWIN 似乎是在子窗口重新定位到 ScrolledWindow 的客户区域之前发布的;换句话说,我正在测量滚动条移动之前的可见对象。有没有办法:a)强制 ScrolledWindow 更新子窗口位置,b)可靠地确定新的客户端窗口偏移量与现在相比,或者 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)

【问题讨论】:

  • 您尝试过ThumbNailCtrl 小部件吗?
  • 不幸的是,我认为在这种情况下我做不到,至少在没有很多麻烦的情况下是做不到的。该小部件似乎是从图像文件目录构建缩略图,而我正在构建代表单个大文件部分的缩略图;所以我必须解析我的文件,将图像保存到磁盘,然后通过小部件重新加载图像。但是,感谢您指出这一点:我将来可能会发现它的用途,并且由于它似乎是 Python 实现(而不是 C++ 包装器),我可以在代码中四处寻找并从中学习。跨度>

标签: python-2.7 wxpython scrolledwindow


【解决方案1】:

在为此苦苦挣扎了一段时间后,我决定绑定 EVT_PAINT 而不是 EVT_SCROLLWIN,并在发生这种情况时检查滚动条。重绘发生在 EVT_SCROLLWIN 和子窗口位置更新之后。

我对这个解决方案不太满意,因为 EVT_PAINT 发生的原因有很多,与滚动条无关,所以如果你有更好的解决方案,请随时指出一个更好的解决方案。幸运的是,在这种情况下,计算会很快通过,除非我添加或删除缩略图(大多数绘制事件不会发生这种情况),因此对性能的影响很小。

【讨论】:

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