QML ListView 如何估计其 contentItem 的高度/宽度

2024-04-09

我想知道如何ListView估计它的高度/宽度contentItem,尽管代表是Component您无法询问,并且不同委托实例的大小可能有所不同。

  • 它不使用当前实例的平均大小。
    否则在实施例1,如果按下一个元素,则估计大小将为3055.5如果计算了所有实例,或者3125如果只计算视图中的那些。据估计2845
  • 它不使用所有当前实例的最大大小。
    如果按下一个元素,则估计大小将为7500。如果仅考虑非实例化元素的最大高度,则为6350
  • 它不使用所有当前实例的最小大小。
    估计肯定是太小了。

即使你知道合适的尺寸,你也无法控制,因为实施例1我们知道正确的contentHeight将会2500如果没有按下任何按钮,并且2650如果有东西被按下。在实施例2正确的contentHeight将会1225但手动设置该值是没有用的,因为它很快就会被覆盖。

示例1:

ListView {
    id: lv1
    width: 200
    height: 500
    model: 50
    onContentHeightChanged: console.log('estimated contentHeight', contentHeight)
    delegate: Rectangle {
        width: 200
        height: ma.pressed ? 150 : 50
        border.color: 'black'
        Text {
            anchors.centerIn: parent
            text: index
        }

        MouseArea {
            id: ma
            anchors.fill: parent
        }
    }
}

示例2:

ListView {
    id: lv1
    width: 200
    height: 500
    model: 50
    onContentHeightChanged: console.log('estimated contentHeight', contentHeight)
    delegate: Rectangle {
        width: 200
        height: index
        border.color: 'black'
        Text {
            anchors.centerIn: parent
            text: index + ' ' + ((index * (index + 1)) / 2)
        }
    }
}

我不知道。我们来看看源代码。 :)

查看代码,here's http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickitemview.cpp哪里的contentWidth and contentHeight已设置:

void QQuickItemViewPrivate::updateViewport()
{
    Q_Q(QQuickItemView);
    qreal extra = headerSize() + footerSize();
    qreal contentSize = isValid() || !visibleItems.isEmpty() ? (endPosition() - startPosition()) : 0.0;
    if (layoutOrientation() == Qt::Vertical)
        q->setContentHeight(contentSize + extra);
    else
        q->setContentWidth(contentSize + extra);
}

The startPosition() and endPosition()函数被声明here http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickitemview.cpp#n1596:

qreal QQuickItemViewPrivate::startPosition() const
{
    return isContentFlowReversed() ? -lastPosition() : originPosition();
}

qreal QQuickItemViewPrivate::endPosition() const
{
    return isContentFlowReversed() ? -originPosition() : lastPosition();
}

QQuickListView的实现originPosition() and lastPosition()都是here http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquicklistview.cpp#n423:

qreal QQuickListViewPrivate::originPosition() const
{
    qreal pos = 0;
    if (!visibleItems.isEmpty()) {
        pos = (*visibleItems.constBegin())->position();
        if (visibleIndex > 0)
            pos -= visibleIndex * (averageSize + spacing);
    }
    return pos;
}

qreal QQuickListViewPrivate::lastPosition() const
{
    qreal pos = 0;
    if (!visibleItems.isEmpty()) {
        int invisibleCount = INT_MIN;
        int delayRemovedCount = 0;
        for (int i = visibleItems.count()-1; i >= 0; --i) {
            if (visibleItems.at(i)->index != -1) {
                // Find the invisible count after the last visible item with known index
                invisibleCount = model->count() - (visibleItems.at(i)->index + 1 + delayRemovedCount);
                break;
            } else if (visibleItems.at(i)->attached->delayRemove()) {
                ++delayRemovedCount;
            }
        }
        if (invisibleCount == INT_MIN) {
            // All visible items are in delayRemove state
            invisibleCount = model->count();
        }
        pos = (*(--visibleItems.constEnd()))->endPosition();
        if (invisibleCount > 0)
            pos += invisibleCount * (averageSize + spacing);
    } else if (model && model->count()) {
        pos = (model->count() * averageSize + (model->count()-1) * spacing);
    }
    return pos;
}

averageSize似乎是经过计算的here http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquicklistview.cpp#n1286:

void QQuickListViewPrivate::updateAverage()
{
    if (!visibleItems.count())
        return;
    qreal sum = 0.0;
    for (int i = 0; i < visibleItems.count(); ++i)
        sum += visibleItems.at(i)->size();
    averageSize = qRound(sum / visibleItems.count());
}

该函数被调用QQuickListViewPrivate::visibleItemsChanged() http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquicklistview.cpp#n767,这被称为QQuickItemViewPrivate::refill() http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickitemview.cpp#n1796,到处都被称为...。基本上每当anything与视图或其项目更改相关。

visibleItems.at(i)->size() is 几乎相当 http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickitemview_p_p.h#n77 to QQuickItem::width()/QQuickItem::height():

inline qreal itemWidth() const { return item ? item->width() : 0; }
inline qreal itemHeight() const { return item ? item->height() : 0; }

从我所看到的来看,它或多或少需要视图中每个可见项目的高度(可能等同于“当前实例化”),将它们加在一起,然后将该总和除以可见项目的数量。您可以通过添加以下调试输出来确认这一点:

$ git diff
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 0351077..acfb88a 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -1296,6 +1296,7 @@ void QQuickListViewPrivate::updateAverage()
     for (FxViewItem *item : qAsConst(visibleItems))
         sum += item->size();
     averageSize = qRound(sum / visibleItems.count());
+    qDebug() << "sum" << sum << "visibleItems.count()" << visibleItems.count();
 }

 qreal QQuickListViewPrivate::headerSize() const

单击某个项目之前的输出:

qml: estimated contentHeight 5000
sum 550 visibleItems.count() 11
qml: estimated contentHeight 2500
sum 850 visibleItems.count() 17

按第一项后:

sum 850 visibleItems.count() 15
qml: estimated contentHeight 2845

所以我想说

它不使用当前实例的平均大小。

在某种程度上是不正确的。如果您确实想知道有什么区别,则需要进一步查看代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QML ListView 如何估计其 contentItem 的高度/宽度 的相关文章

  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我
  • AStar-名称解释

    我正在寻找 AStar A 算法为何被称为 AStar 的解释 所有类似的 最短路径问题 算法通常都以其开发者的名字命名 那么 AStar 代表什么 有称为 A1 和 A2 的算法 后来证明A2是最优的 实际上也是可能的最好算法 所以他给它
  • 如何在 Android 中使列表视图中的项目不可点击

    如何使列表视图中的项目无法单击 我在列表视图中获得了主题和项目 但主题和项目的视图相同 项目可单击 但主题不可单击 如何实现这一目标 该列表看起来像 Topic item Topic item item 话题 单击able false 不起
  • 来自另一个类的 Qt C++ GUI 调用

    我通过 gui 拖放创建了一个按钮和一个文本浏览器 UI 以及单击按钮功能是在 mainwindow cpp 中创建的 有一个 main cpp 但这是无关紧要的 因为在单击开始按钮之前程序不会启动 include mainwindow h
  • 如何使用 python 有效地找到两个大文件的交集?

    我有两个大文件 它们的内容如下所示 134430513125296589151963957125296589 该文件包含未排序的 id 列表 某些 id 可能会在单个文件中出现多次 现在我想找到路口两个文件的一部分 这就是两个文件中都出现的
  • 并行化斐波那契序列生成器

    我正在学习并行化 在一项练习中 我得到了一些我应该提高性能的算法 其中之一是斐波那契数列生成器 array 0 0 array 1 1 for q 2 q lt MAX q array q array q 1 array q 2 我怀疑 这
  • 滚动或滑动窗口迭代器?

    我需要一个可在序列 迭代器 生成器上迭代的滚动窗口 又名滑动窗口 默认的 Python 迭代可以被视为一种特殊情况 其中窗口长度为 1 我当前正在使用以下代码 我怎样才能更优雅和 或更有效地做到这一点 def rolling window
  • 贪心技术与穷举搜索有何不同?

    我正在为一些示例问题编写伪代码 并且我注意到贪婪技术和详尽搜索之间存在令人担忧的模式 Job 1 Job 2 Job 3 Job 4 Job 5 Person 1 9 2 7 8 Person 2 6 4 3 7 Person 3 5 8
  • 如何高效生成总和在指定范围内的所有组合(在所有深度)

    假设您有一组值 1 1 1 12 12 16 如何生成总和在预定义范围内的所有可能组合 不重复 min max 例如 这里是 所有深度的 范围在13 and 17 1 12 1 1 12 1 1 1 12 16 1 16 这假设具有相同值的
  • 压缩很多小字符串的算法?

    我正在寻找一种压缩小 ASCII 字符串的算法 它们包含大量字母 但也可以包含数字和很少的特殊字符 它们很小 平均约为 50 100 字节 最多 250 个字节 例子 Android show EditText setError above
  • QWidget::showMinimized() 不起作用

    在 Ubuntu 13 04 上 如果使用QWidget showMinimized 为了最小化窗口 我发现通过单击系统任务栏上的应用程序图标恢复它后 调用QWidget showMinimized 无法工作 connect minimum
  • 依次构建完整的 B 树

    如果我有一组排序的数据 我想以最适合顺序读取和随机查找的方式将其存储在磁盘上 那么 B 树 或其中一个变体 似乎是一个不错的选择 假设该数据集并不全部适合 RAM 问题是可以从一组排序的数据构建完整的 B 树而不进行任何页面拆分吗 这样排序
  • 将数字的各个数字部分相加/求和的最快方法

    不久前 我在数学论坛上看到一个问题 其中一个人正在讨论一遍又一遍地将数字中的数字相加 直到达到个位数 即 362 将变成 3 6 2 这将变成 11 然后 11 将变成 1 1 将变成 2 因此 362 将返回2 我写了一些很好的代码来得到
  • 最接近 x,y 的线上的点[重复]

    这个问题在这里已经有答案了 可能的重复 如何判断一个点是否在某条线附近 https stackoverflow com questions 910882 how can i tell if a point is nearby a certa
  • 常量类成员、赋值运算符和 QList

    请确认我是否正确并告诉我是否有更好的解决方案 我了解具有常量成员的对象 例如int const width 无法由编译器隐式创建的合成赋值运算符处理 但是 QList 我想 std list 也是如此 需要一个有效的赋值运算符 因此 当我想
  • 数字求和的算法?

    我正在寻找一种数字求和的算法 让我概述一下基本原则 假设你有一个号码 18268 1 8 2 6 8 25 2 5 7 7 是我们的最终数字 它基本上是将整个数字中的每个数字相加 直到我们得到一个 也称为 核心 数字 它经常被命理学家使用
  • 面向 Delphi 开发人员的 Qt

    有人知道为 Delphi C Builder VCL 开发人员解释 Qt 的书籍或教程吗 对于具有该背景的开发人员来说 学习 Qt 的最佳方法是什么 我对如何使用 Qt 完成我知道如何在 Delphi 中完成的事情特别感兴趣 例如 Qt 相
  • 如何使用 ClangCodeModel 插件在 QtCreator 中设置 C++ 标准?

    抱歉 如果这是一个愚蠢的问题 但我已经尝试了几乎所有的方法 现在正在用头撞墙 问题是 带有 Clang 代码模型插件的 QtCreator 4 8 0 beta for Windows 解析我的项目 为 C 98 而实际上它是 C 17 但
  • 如何将枚举类传递给 QML?

    我正在学习QML with Qt并在通过时遇到一些麻烦enum class to qml 当我使用信号时int参数 一切正常 代码运行完美 But 麻烦就在这里 如果我使用信号与一些enum class我有参数undefinedqml 信号
  • Diamond-Square 算法的平滑问题

    我正在使用菱形方形算法来生成随机地形 它工作得很好 除了我让这些大圆锥形状要么伸出或伸入地形 问题似乎在于 时不时会有一个点被设置得太高或太低 Here is a picture of the problem And it can be b

随机推荐