4

I have C++ Qt 5.2.1 based project and one of graphic component looks like:

 +-- ParentWidget == QScrollArea ----------+
 |                                       |^|
 | +-- MiddleWidget == QWidget -------+  | |
 | | (>) Expand/collapse button       |  | |
 | |----------------------------------|  | |
 | |                                  |  | |
 | | +-- ChildWidget ---------------+ |  | |
 | | | ...                          | |  |0|
 | | +------------------------------+ |  |0|
 | |                                  |  |0|
 | | +-- ChildWidget ---------------+ |  |0|
 | | | ...                          | |  |0|
 | | +------------------------------+ |  |0|
 | |                                  |  |0|
 | | ...                              |  |0|
 | +----------------------------------+  |0|
 |                                       |0|
 | +-- MiddleWidget == QWidget -------+  |0|
 | | (>) Expand/collapse button       |  | |
 | |----------------------------------|  | |
 | |                                  |  | |
 | | +-- ChildWidget ---------------+ |  | |
 | | | ...                          | |  | |
 | | +------------------------------+ |  | |
 | |                                  |  | |
 | | +-- ChildWidget ---------------+ |  | |
 | | | ...                          | |  | |
 +-----------------------------------------+

So, ParentWidget is QScrollArea, others are QWidgets. ParentWidget contains some MiddleWidgets, MiddleWidget contains some ChildWidgets. MiddleWidget also can be expanded or collapsed - when collapsed, ChildWidgets are not "visible" (isVisible() == false).

When user scrolls ParentWidget up and down, ChildWidgets which are "visible" (isVisible() == true) can actually be not real visible on screen. ChildWidgets contains pictures, and it's inefficiently to store all pictures in memory. So i want to load picture when ChildWidget is really appears on screen and user sees it; when ChildWidget disappears, picture should be stored to file and erased from memory.

Right now i can check such real visibility changing via ParentWidget:

bool ParentWidget::eventFilter(QObject *object, QEvent *event)
{
    if (object == widget() && event->type() == QEvent::Paint) {
        for (auto middle : _middles) {
            for (auto child : middle->childs()) {
                if (!child->visibleRegion().isEmpty()) {
                    ...
                }
            }
        }
    }

    return QScrollArea::eventFilter(object, event);
}

But this way obviously has its disadvantages:

  • ChildWidgets don't know about change their real visibility and depends on ParentWidget
  • when ParentWidget's paint event occurs, all ChildWidgets should be checked

So my question is: can QWidget catch changing its real visibility state itself? If no, maybe there is more effective way to implement such behaviour?

4

1 回答 1

3

QWidget 可以捕捉到改变其真实可见性状态本身吗?

不。

小部件知道它是否可见的唯一真正方法是在它执行时paintEvent。但是小部件无法知道它真的不可见。

所以我想在 ChildWidget 真正出现在屏幕上并且用户看到它时加载图片;当 ChildWidget 消失时,图片应该存储到文件中并从内存中删除。

你看过图形视图框架吗?它旨在有效地处理大量项目,并且速度非常快。

编辑:我从未使用过它,但有QPixmapCache。您可以在实例之间共享缓存ChildWidget并管理可用像素图的限制。
有一个关于如何使用 Qpixmap 缓存的教程。

于 2015-01-21T13:02:03.177 回答