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 的高度/宽度 的相关文章

  • Qt中如何获取鼠标在屏幕上的位置?

    我想获取屏幕上的鼠标坐标 我怎样才能在 Qt 中做到这一点 在 Windows 上 使用 C 我正在做类似答案中建议的事情对于这个问题 https stackoverflow com q 11737665 1420197 正如文档所述 QC
  • Qt mouseReleaseEvent() 未触发?

    我有一个显示图片的库 我们称之为 PictureGLWidget 其中 class PictureGLWidget public QGLWidget 所以 PictureGLWidget 扩展了 QGLWidget 在PictureGlWi
  • 我需要一个支持高效随机访问和 O(k) 插入和删除的容器

    我再次尝试问同样的问题question https stackoverflow com questions 3808708 delete parts of a dynamic array and grow other 但我最终提出了一个不同
  • C#设置ListView的Item的Subitem的文本不显示

    我在这里有点失去理智了 当我最初构建 ListView 时 它完全按预期工作 ListViewItem listViewItem listView Items Add model Id ToString model Name model I
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • QTcpSocket 有时不发送数据

    我有两个 QT 应用程序 一个应用程序可以被认为保存了大数据 它每秒向第二个应用程序发送大约 10 KB 的数据块 之前我尝试使用QUdpSocket来传输数据 但由于MTU限制在2 5K左右 并且需要自己分割和重新组合数据 所以我改用QT
  • 如何将一组重叠范围划分为不重叠范围?

    假设您有一组范围 0 100 一 0 75 b 95 150 c 120 130 d 显然 这些范围在某些点上重叠 您将如何剖析这些范围以生成不重叠范围的列表 同时保留与其原始范围相关的信息 在本例中为范围后面的字母 例如 运行算法后的上述
  • PyQt:如何设置组合框项目可检查?

    为了将 GUI 小部件数量保持在最低限度 我需要找到一种方法来为用户提供下拉菜单项的选择 这些菜单项可用于过滤掉 listWidget 项中显示的内容 假设 listWidget 列出了 5 个不同类别的项目 Cat A Cat B Cat
  • 错误 LNK2001:无法解析的外部符号 __CxxFrameHandler3

    我正在将 Qt 从 VS 2013 迁移到 Qt 5 10 1 到 VS 2015 出现以下多个链接错误 error LNK2001 unresolved external symbol CxxFrameHandler3 error LNK
  • 解释一下从 N 个给定集合中的每一个中给出第 K 个最大数字的示例?

    今天我尝试解决一个Facebook 编程挑战赛 https facebook interviewstreet com recruit challenges 我遇到的挑战是 酒吧问题 可以找到here https github com alo
  • QGraphicsScene::clear 不会改变 sceneRect

    我有一个 QGraphicsScene 场景 和 QGraphicsView graphicsView 我有一个画图的方法 当我需要重绘所有图形时 我调用这个方法 一切都好 但我意识到 scene gt clear 不会改变 sceneRe
  • 向 Qt 样式表添加特异性时丢失样式

    这是我的代码 const QString STYLE SHEET background color rgba x x x y border 1px solid gray border radius 0px border top 1px so
  • 无需构建树即可预测霍夫曼压缩比

    我有一个二进制文件 我知道其中每个符号出现的次数 如果我要使用霍夫曼算法压缩它 我需要预测压缩文件的长度 我只对假设的输出长度感兴趣 而不对单个符号的代码感兴趣 因此构建霍夫曼树似乎是多余的 作为一个例子 我需要得到类似的东西 包含 4 个
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • URL路径相似度/字符串相似度算法

    我的问题是我需要比较 URL 路径并推断它们是否相似 下面我提供了要处理的示例数据 GROUP 1 robots txt GROUP 2 bot html GROUP 3 phpMyAdmin 2 5 6 rc1 scripts setup
  • 生成所有多集大小为 n 的分区的算法

    我一直在试图找出一种方法来生成多重集的所有不同的大小为 n 的分区 但到目前为止却空手而归 首先让我展示一下我想要实现的目标 假设我们有一个输入向量uint32 t std vector
  • 用 C++ 生成 AST

    我正在用 C 制作一个解释器 到目前为止我已经有了词法分析器来生成标记 问题是我不确定如何生成 行走 解析树 我正在考虑使用数组数组来制作解析树 但我不确定如何以正确的顺序将标记实际插入到解析树中 我不确定是自上而下 左右还是自下而上 左右
  • 在android中从JSON生成listview

    我对 Android 完全陌生 目前正在尝试从从我的服务器中提取的 JSON 数组生成列表视图 我已经阅读了很多教程 但没有运气 有一种独特的方法可以做到这一点 请您指出一些适合开始的资源 我读过了this http www josecgo
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959

随机推荐