4

C++ Qt 5.2.1 ベースのプロジェクトがあり、グラフィック コンポーネントの 1 つが次のようになります。

 +-- 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 ---------------+ |  | |
 | | | ...                          | |  | |
 +-----------------------------------------+

したがって、ParentWidget は QScrollArea であり、その他は QWidget です。ParentWidget にはいくつかの MiddleWidget が含まれ、MiddleWidget にはいくつかの ChildWidget が含まれます。MiddleWidget は、展開または折りたたむこともできます。折りたたむと、ChildWidget は「表示」されません (isVisible() == false)。

ユーザーが ParentWidget を上下にスクロールすると、「可視」(isVisible() == true) の ChildWidget が実際には画面に表示されない場合があります。ChildWidgets には画像が含まれており、すべての画像をメモリに格納するのは非効率的です。だから私は ChildWidget が実際に画面に表示され、ユーザーがそれを見たときに画像をロードしたい。ChildWidget が消えたら、画像をファイルに保存し、メモリから消去する必要があります。

現在、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);
}

しかし、この方法には明らかに欠点があります。

  • ChildWidgets は実際の可視性の変更を認識せず、ParentWidget に依存します
  • ParentWidget のペイント イベントが発生すると、すべての ChildWidgets をチェックする必要があります

だから私の質問は: QWidget は実際の可視性状態自体の変更をキャッチできますか? いいえの場合、そのような動作を実装するためのより効果的な方法があるでしょうか?

4

1 に答える 1

3

QWidget は、実際の可視性状態自体の変更をキャッチできますか?

いいえ。

ウィジェットが可視であることを知る唯一の実際の方法は、ウィジェットが実行されるときpaintEventです。しかし、ウィジェットには、実際に表示されていないことを知る方法がありません。

だから私は ChildWidget が実際に画面に表示され、ユーザーがそれを見たときに画像をロードしたい。ChildWidget が消えたら、画像をファイルに保存し、メモリから消去する必要があります。

グラフィック ビュー フレームワークを見ましたか? 大量のアイテムを効率的に処理し、非常に高速に処理できるように設計されています。

編集:使用したことはありませんが、 QPixmapCacheがあります。インスタンス間でキャッシュを共有し、ChildWidget使用可能なピックスマップの制限を管理できます。
Qpixmap キャッシュの使用方法に関するチュートリアルがあります。

于 2015-01-21T13:02:03.177 に答える